file.c 28.1 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
T
Tejun Heo 已提交
2 3 4 5 6 7 8 9 10
 * fs/sysfs/file.c - sysfs regular (text) file implementation
 *
 * Copyright (c) 2001-3 Patrick Mochel
 * Copyright (c) 2007 SUSE Linux Products GmbH
 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
 *
 * This file is released under the GPLv2.
 *
 * Please see Documentation/filesystems/sysfs.txt for more information.
L
Linus Torvalds 已提交
11 12 13 14
 */

#include <linux/module.h>
#include <linux/kobject.h>
15
#include <linux/kallsyms.h>
16
#include <linux/slab.h>
M
Miklos Szeredi 已提交
17
#include <linux/fsnotify.h>
18
#include <linux/namei.h>
19
#include <linux/poll.h>
20
#include <linux/list.h>
21
#include <linux/mutex.h>
A
Andrew Morton 已提交
22
#include <linux/limits.h>
23
#include <linux/uaccess.h>
24
#include <linux/seq_file.h>
25
#include <linux/mm.h>
L
Linus Torvalds 已提交
26 27 28

#include "sysfs.h"

T
Tejun Heo 已提交
29
/*
30
 * There's one sysfs_open_file for each open file and one sysfs_open_dirent
T
Tejun Heo 已提交
31
 * for each sysfs_dirent with one or more open files.
T
Tejun Heo 已提交
32
 *
T
Tejun Heo 已提交
33 34 35
 * sysfs_dirent->s_attr.open points to sysfs_open_dirent.  s_attr.open is
 * protected by sysfs_open_dirent_lock.
 *
36 37
 * filp->private_data points to seq_file whose ->private points to
 * sysfs_open_file.  sysfs_open_files are chained at
38
 * sysfs_open_dirent->files, which is protected by sysfs_open_file_mutex.
T
Tejun Heo 已提交
39
 */
J
Jiri Slaby 已提交
40
static DEFINE_SPINLOCK(sysfs_open_dirent_lock);
T
Tejun Heo 已提交
41
static DEFINE_MUTEX(sysfs_open_file_mutex);
T
Tejun Heo 已提交
42 43 44

struct sysfs_open_dirent {
	atomic_t		refcnt;
45 46
	atomic_t		event;
	wait_queue_head_t	poll;
47
	struct list_head	files; /* goes through sysfs_open_file.list */
T
Tejun Heo 已提交
48 49
};

50
struct sysfs_open_file {
51 52
	struct sysfs_dirent	*sd;
	struct file		*file;
53
	struct mutex		mutex;
T
Tejun Heo 已提交
54
	int			event;
T
Tejun Heo 已提交
55
	struct list_head	list;
56 57 58

	bool			mmapped;
	const struct vm_operations_struct *vm_ops;
T
Tejun Heo 已提交
59
};
L
Linus Torvalds 已提交
60

61 62 63 64 65
static bool sysfs_is_bin(struct sysfs_dirent *sd)
{
	return sysfs_type(sd) == SYSFS_KOBJ_BIN_ATTR;
}

66 67 68 69 70
static struct sysfs_open_file *sysfs_of(struct file *file)
{
	return ((struct seq_file *)file->private_data)->private;
}

T
Tejun Heo 已提交
71 72 73 74 75 76
/*
 * Determine ktype->sysfs_ops for the given sysfs_dirent.  This function
 * must be called while holding an active reference.
 */
static const struct sysfs_ops *sysfs_file_ops(struct sysfs_dirent *sd)
{
77
	struct kobject *kobj = sd->s_parent->priv;
T
Tejun Heo 已提交
78

79 80
	if (!sysfs_ignore_lockdep(sd))
		lockdep_assert_held(sd);
T
Tejun Heo 已提交
81 82 83
	return kobj->ktype ? kobj->ktype->sysfs_ops : NULL;
}

84 85 86 87
/*
 * Reads on sysfs are handled through seq_file, which takes care of hairy
 * details like buffering and seeking.  The following function pipes
 * sysfs_ops->show() result through seq_file.
L
Linus Torvalds 已提交
88
 */
89
static int sysfs_kf_seq_show(struct seq_file *sf, void *v)
L
Linus Torvalds 已提交
90
{
91
	struct sysfs_open_file *of = sf->private;
92
	struct kobject *kobj = of->sd->s_parent->priv;
93
	const struct sysfs_ops *ops = sysfs_file_ops(of->sd);
L
Linus Torvalds 已提交
94
	ssize_t count;
95
	char *buf;
L
Linus Torvalds 已提交
96

97 98 99 100 101 102
	/* acquire buffer and ensure that it's >= PAGE_SIZE */
	count = seq_get_buf(sf, &buf);
	if (count < PAGE_SIZE) {
		seq_commit(sf, -1);
		return 0;
	}
L
Linus Torvalds 已提交
103

104
	/*
105 106
	 * Invoke show().  Control may reach here via seq file lseek even
	 * if @ops->show() isn't implemented.
107
	 */
108
	if (ops->show) {
109
		count = ops->show(kobj, of->sd->priv, buf);
110 111 112
		if (count < 0)
			return count;
	}
113

114 115 116 117
	/*
	 * The code works fine with PAGE_SIZE return but it's likely to
	 * indicate truncated result or overflow in normal use cases.
	 */
118 119 120 121 122 123
	if (count >= (ssize_t)PAGE_SIZE) {
		print_symbol("fill_read_buffer: %s returned bad count\n",
			(unsigned long)ops->show);
		/* Try to struggle along */
		count = PAGE_SIZE - 1;
	}
124 125
	seq_commit(sf, count);
	return 0;
L
Linus Torvalds 已提交
126 127
}

128 129
static ssize_t sysfs_kf_bin_read(struct sysfs_open_file *of, char *buf,
				 size_t count, loff_t pos)
T
Tejun Heo 已提交
130
{
131 132
	struct bin_attribute *battr = of->sd->priv;
	struct kobject *kobj = of->sd->s_parent->priv;
133
	loff_t size = file_inode(of->file)->i_size;
T
Tejun Heo 已提交
134

135
	if (!count)
T
Tejun Heo 已提交
136 137 138
		return 0;

	if (size) {
139
		if (pos > size)
T
Tejun Heo 已提交
140
			return 0;
141 142
		if (pos + count > size)
			count = size - pos;
T
Tejun Heo 已提交
143 144
	}

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
	if (!battr->read)
		return -EIO;

	return battr->read(of->file, kobj, battr, buf, pos, count);
}

static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos)
{
	struct sysfs_open_file *of = sf->private;

	/*
	 * @of->mutex nests outside active ref and is just to ensure that
	 * the ops aren't called concurrently for the same open file.
	 */
	mutex_lock(&of->mutex);
	if (!sysfs_get_active(of->sd))
		return ERR_PTR(-ENODEV);

	/*
	 * The same behavior and code as single_open().  Returns !NULL if
	 * pos is at the beginning; otherwise, NULL.
	 */
	return NULL + !*ppos;
}

static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos)
{
	/*
	 * The same behavior and code as single_open(), always terminate
	 * after the initial read.
	 */
	++*ppos;
	return NULL;
}

static void kernfs_seq_stop(struct seq_file *sf, void *v)
{
	struct sysfs_open_file *of = sf->private;

	sysfs_put_active(of->sd);
	mutex_unlock(&of->mutex);
}

static int kernfs_seq_show(struct seq_file *sf, void *v)
{
	struct sysfs_open_file *of = sf->private;

	of->event = atomic_read(&of->sd->s_attr.open->event);

	return sysfs_kf_seq_show(sf, v);
}

static const struct seq_operations kernfs_seq_ops = {
	.start = kernfs_seq_start,
	.next = kernfs_seq_next,
	.stop = kernfs_seq_stop,
	.show = kernfs_seq_show,
};

/*
 * As reading a bin file can have side-effects, the exact offset and bytes
 * specified in read(2) call should be passed to the read callback making
 * it difficult to use seq_file.  Implement simplistic custom buffering for
 * bin files.
 */
static ssize_t kernfs_file_direct_read(struct sysfs_open_file *of,
				       char __user *user_buf, size_t count,
				       loff_t *ppos)
{
	ssize_t len = min_t(size_t, count, PAGE_SIZE);
	char *buf;

	buf = kmalloc(len, GFP_KERNEL);
T
Tejun Heo 已提交
218 219 220
	if (!buf)
		return -ENOMEM;

221 222 223 224
	/*
	 * @of->mutex nests outside active ref and is just to ensure that
	 * the ops aren't called concurrently for the same open file.
	 */
T
Tejun Heo 已提交
225 226
	mutex_lock(&of->mutex);
	if (!sysfs_get_active(of->sd)) {
227
		len = -ENODEV;
T
Tejun Heo 已提交
228 229 230 231
		mutex_unlock(&of->mutex);
		goto out_free;
	}

232
	len = sysfs_kf_bin_read(of, buf, len, *ppos);
T
Tejun Heo 已提交
233 234 235 236

	sysfs_put_active(of->sd);
	mutex_unlock(&of->mutex);

237
	if (len < 0)
T
Tejun Heo 已提交
238 239
		goto out_free;

240 241
	if (copy_to_user(user_buf, buf, len)) {
		len = -EFAULT;
T
Tejun Heo 已提交
242 243 244
		goto out_free;
	}

245
	*ppos += len;
T
Tejun Heo 已提交
246 247 248

 out_free:
	kfree(buf);
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
	return len;
}

/**
 * kernfs_file_read - kernfs vfs read callback
 * @file: file pointer
 * @user_buf: data to write
 * @count: number of bytes
 * @ppos: starting offset
 */
static ssize_t kernfs_file_read(struct file *file, char __user *user_buf,
				size_t count, loff_t *ppos)
{
	struct sysfs_open_file *of = sysfs_of(file);

	if (sysfs_is_bin(of->sd))
		return kernfs_file_direct_read(of, user_buf, count, ppos);
	else
		return seq_read(file, user_buf, count, ppos);
T
Tejun Heo 已提交
268 269
}

270 271 272
/* kernfs write callback for regular sysfs files */
static ssize_t sysfs_kf_write(struct sysfs_open_file *of, char *buf,
			      size_t count, loff_t pos)
L
Linus Torvalds 已提交
273
{
274
	const struct sysfs_ops *ops = sysfs_file_ops(of->sd);
275
	struct kobject *kobj = of->sd->s_parent->priv;
276

277 278
	if (!count)
		return 0;
279

280 281
	return ops->store(kobj, of->sd->priv, buf, count);
}
282

283 284 285 286 287 288 289
/* kernfs write callback for bin sysfs files */
static ssize_t sysfs_kf_bin_write(struct sysfs_open_file *of, char *buf,
				  size_t count, loff_t pos)
{
	struct bin_attribute *battr = of->sd->priv;
	struct kobject *kobj = of->sd->s_parent->priv;
	loff_t size = file_inode(of->file)->i_size;
290

291 292 293 294
	if (size) {
		if (size <= pos)
			return 0;
		count = min_t(ssize_t, count, size - pos);
295
	}
296 297
	if (!count)
		return 0;
298

299 300
	if (!battr->write)
		return -EIO;
L
Linus Torvalds 已提交
301

302
	return battr->write(of->file, kobj, battr, buf, pos, count);
L
Linus Torvalds 已提交
303 304 305
}

/**
306
 * kernfs_file_write - kernfs vfs write callback
T
Tejun Heo 已提交
307 308 309 310 311
 * @file: file pointer
 * @user_buf: data to write
 * @count: number of bytes
 * @ppos: starting offset
 *
312 313
 * Copy data in from userland and pass it to the matching kernfs write
 * operation.
L
Linus Torvalds 已提交
314
 *
T
Tejun Heo 已提交
315 316 317 318 319
 * There is no easy way for us to know if userspace is only doing a partial
 * write, so we don't support them. We expect the entire buffer to come on
 * the first write.  Hint: if you're writing a value, first read the file,
 * modify only the the value you're changing, then write entire buffer
 * back.
L
Linus Torvalds 已提交
320
 */
321 322
static ssize_t kernfs_file_write(struct file *file, const char __user *user_buf,
				 size_t count, loff_t *ppos)
L
Linus Torvalds 已提交
323
{
324
	struct sysfs_open_file *of = sysfs_of(file);
325
	ssize_t len = min_t(size_t, count, PAGE_SIZE);
T
Tejun Heo 已提交
326
	char *buf;
L
Linus Torvalds 已提交
327

T
Tejun Heo 已提交
328 329 330 331 332 333 334 335 336 337
	buf = kmalloc(len + 1, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	if (copy_from_user(buf, user_buf, len)) {
		len = -EFAULT;
		goto out_free;
	}
	buf[len] = '\0';	/* guarantee string termination */

338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
	/*
	 * @of->mutex nests outside active ref and is just to ensure that
	 * the ops aren't called concurrently for the same open file.
	 */
	mutex_lock(&of->mutex);
	if (!sysfs_get_active(of->sd)) {
		mutex_unlock(&of->mutex);
		len = -ENODEV;
		goto out_free;
	}

	if (sysfs_is_bin(of->sd))
		len = sysfs_kf_bin_write(of, buf, len, *ppos);
	else
		len = sysfs_kf_write(of, buf, len, *ppos);

	sysfs_put_active(of->sd);
	mutex_unlock(&of->mutex);

L
Linus Torvalds 已提交
357 358
	if (len > 0)
		*ppos += len;
T
Tejun Heo 已提交
359 360
out_free:
	kfree(buf);
L
Linus Torvalds 已提交
361 362 363
	return len;
}

364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
static void sysfs_bin_vma_open(struct vm_area_struct *vma)
{
	struct file *file = vma->vm_file;
	struct sysfs_open_file *of = sysfs_of(file);

	if (!of->vm_ops)
		return;

	if (!sysfs_get_active(of->sd))
		return;

	if (of->vm_ops->open)
		of->vm_ops->open(vma);

	sysfs_put_active(of->sd);
}

static int sysfs_bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
	struct file *file = vma->vm_file;
	struct sysfs_open_file *of = sysfs_of(file);
	int ret;

	if (!of->vm_ops)
		return VM_FAULT_SIGBUS;

	if (!sysfs_get_active(of->sd))
		return VM_FAULT_SIGBUS;

	ret = VM_FAULT_SIGBUS;
	if (of->vm_ops->fault)
		ret = of->vm_ops->fault(vma, vmf);

	sysfs_put_active(of->sd);
	return ret;
}

static int sysfs_bin_page_mkwrite(struct vm_area_struct *vma,
				  struct vm_fault *vmf)
{
	struct file *file = vma->vm_file;
	struct sysfs_open_file *of = sysfs_of(file);
	int ret;

	if (!of->vm_ops)
		return VM_FAULT_SIGBUS;

	if (!sysfs_get_active(of->sd))
		return VM_FAULT_SIGBUS;

	ret = 0;
	if (of->vm_ops->page_mkwrite)
		ret = of->vm_ops->page_mkwrite(vma, vmf);
	else
		file_update_time(file);

	sysfs_put_active(of->sd);
	return ret;
}

static int sysfs_bin_access(struct vm_area_struct *vma, unsigned long addr,
			    void *buf, int len, int write)
{
	struct file *file = vma->vm_file;
	struct sysfs_open_file *of = sysfs_of(file);
	int ret;

	if (!of->vm_ops)
		return -EINVAL;

	if (!sysfs_get_active(of->sd))
		return -EINVAL;

	ret = -EINVAL;
	if (of->vm_ops->access)
		ret = of->vm_ops->access(vma, addr, buf, len, write);

	sysfs_put_active(of->sd);
	return ret;
}

#ifdef CONFIG_NUMA
static int sysfs_bin_set_policy(struct vm_area_struct *vma,
				struct mempolicy *new)
{
	struct file *file = vma->vm_file;
	struct sysfs_open_file *of = sysfs_of(file);
	int ret;

	if (!of->vm_ops)
		return 0;

	if (!sysfs_get_active(of->sd))
		return -EINVAL;

	ret = 0;
	if (of->vm_ops->set_policy)
		ret = of->vm_ops->set_policy(vma, new);

	sysfs_put_active(of->sd);
	return ret;
}

static struct mempolicy *sysfs_bin_get_policy(struct vm_area_struct *vma,
					      unsigned long addr)
{
	struct file *file = vma->vm_file;
	struct sysfs_open_file *of = sysfs_of(file);
	struct mempolicy *pol;

	if (!of->vm_ops)
		return vma->vm_policy;

	if (!sysfs_get_active(of->sd))
		return vma->vm_policy;

	pol = vma->vm_policy;
	if (of->vm_ops->get_policy)
		pol = of->vm_ops->get_policy(vma, addr);

	sysfs_put_active(of->sd);
	return pol;
}

static int sysfs_bin_migrate(struct vm_area_struct *vma, const nodemask_t *from,
			     const nodemask_t *to, unsigned long flags)
{
	struct file *file = vma->vm_file;
	struct sysfs_open_file *of = sysfs_of(file);
	int ret;

	if (!of->vm_ops)
		return 0;

	if (!sysfs_get_active(of->sd))
		return 0;

	ret = 0;
	if (of->vm_ops->migrate)
		ret = of->vm_ops->migrate(vma, from, to, flags);

	sysfs_put_active(of->sd);
	return ret;
}
#endif

static const struct vm_operations_struct sysfs_bin_vm_ops = {
	.open		= sysfs_bin_vma_open,
	.fault		= sysfs_bin_fault,
	.page_mkwrite	= sysfs_bin_page_mkwrite,
	.access		= sysfs_bin_access,
#ifdef CONFIG_NUMA
	.set_policy	= sysfs_bin_set_policy,
	.get_policy	= sysfs_bin_get_policy,
	.migrate	= sysfs_bin_migrate,
#endif
};

static int sysfs_bin_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct sysfs_open_file *of = sysfs_of(file);
525 526
	struct bin_attribute *battr = of->sd->priv;
	struct kobject *kobj = of->sd->s_parent->priv;
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
	int rc;

	mutex_lock(&of->mutex);

	/* need of->sd for battr, its parent for kobj */
	rc = -ENODEV;
	if (!sysfs_get_active(of->sd))
		goto out_unlock;

	if (!battr->mmap)
		goto out_put;

	rc = battr->mmap(file, kobj, battr, vma);
	if (rc)
		goto out_put;

	/*
	 * PowerPC's pci_mmap of legacy_mem uses shmem_zero_setup()
	 * to satisfy versions of X which crash if the mmap fails: that
	 * substitutes a new vm_file, and we don't then want bin_vm_ops.
	 */
	if (vma->vm_file != file)
		goto out_put;

	rc = -EINVAL;
	if (of->mmapped && of->vm_ops != vma->vm_ops)
		goto out_put;

	/*
	 * It is not possible to successfully wrap close.
	 * So error if someone is trying to use close.
	 */
	rc = -EINVAL;
	if (vma->vm_ops && vma->vm_ops->close)
		goto out_put;

	rc = 0;
	of->mmapped = 1;
	of->vm_ops = vma->vm_ops;
	vma->vm_ops = &sysfs_bin_vm_ops;
out_put:
	sysfs_put_active(of->sd);
out_unlock:
	mutex_unlock(&of->mutex);

	return rc;
}

T
Tejun Heo 已提交
575 576 577
/**
 *	sysfs_get_open_dirent - get or create sysfs_open_dirent
 *	@sd: target sysfs_dirent
578
 *	@of: sysfs_open_file for this instance of open
T
Tejun Heo 已提交
579 580
 *
 *	If @sd->s_attr.open exists, increment its reference count;
581
 *	otherwise, create one.  @of is chained to the files list.
T
Tejun Heo 已提交
582 583 584 585 586 587 588 589
 *
 *	LOCKING:
 *	Kernel thread context (may sleep).
 *
 *	RETURNS:
 *	0 on success, -errno on failure.
 */
static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
590
				 struct sysfs_open_file *of)
T
Tejun Heo 已提交
591 592 593 594
{
	struct sysfs_open_dirent *od, *new_od = NULL;

 retry:
T
Tejun Heo 已提交
595
	mutex_lock(&sysfs_open_file_mutex);
596
	spin_lock_irq(&sysfs_open_dirent_lock);
T
Tejun Heo 已提交
597 598 599 600 601 602 603 604 605

	if (!sd->s_attr.open && new_od) {
		sd->s_attr.open = new_od;
		new_od = NULL;
	}

	od = sd->s_attr.open;
	if (od) {
		atomic_inc(&od->refcnt);
606
		list_add_tail(&of->list, &od->files);
T
Tejun Heo 已提交
607 608
	}

609
	spin_unlock_irq(&sysfs_open_dirent_lock);
T
Tejun Heo 已提交
610
	mutex_unlock(&sysfs_open_file_mutex);
T
Tejun Heo 已提交
611 612 613 614 615 616 617 618 619 620 621 622

	if (od) {
		kfree(new_od);
		return 0;
	}

	/* not there, initialize a new one and retry */
	new_od = kmalloc(sizeof(*new_od), GFP_KERNEL);
	if (!new_od)
		return -ENOMEM;

	atomic_set(&new_od->refcnt, 0);
623 624
	atomic_set(&new_od->event, 1);
	init_waitqueue_head(&new_od->poll);
625
	INIT_LIST_HEAD(&new_od->files);
T
Tejun Heo 已提交
626 627 628 629 630 631
	goto retry;
}

/**
 *	sysfs_put_open_dirent - put sysfs_open_dirent
 *	@sd: target sysfs_dirent
632
 *	@of: associated sysfs_open_file
T
Tejun Heo 已提交
633
 *
634 635
 *	Put @sd->s_attr.open and unlink @of from the files list.  If
 *	reference count reaches zero, disassociate and free it.
T
Tejun Heo 已提交
636 637 638 639 640
 *
 *	LOCKING:
 *	None.
 */
static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
641
				  struct sysfs_open_file *of)
T
Tejun Heo 已提交
642 643
{
	struct sysfs_open_dirent *od = sd->s_attr.open;
644
	unsigned long flags;
T
Tejun Heo 已提交
645

T
Tejun Heo 已提交
646
	mutex_lock(&sysfs_open_file_mutex);
647
	spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
T
Tejun Heo 已提交
648

649 650 651
	if (of)
		list_del(&of->list);

T
Tejun Heo 已提交
652 653 654 655 656
	if (atomic_dec_and_test(&od->refcnt))
		sd->s_attr.open = NULL;
	else
		od = NULL;

657
	spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
T
Tejun Heo 已提交
658
	mutex_unlock(&sysfs_open_file_mutex);
T
Tejun Heo 已提交
659 660 661 662

	kfree(od);
}

663
static int sysfs_open_file(struct inode *inode, struct file *file)
L
Linus Torvalds 已提交
664
{
665
	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
666
	struct kobject *kobj = attr_sd->s_parent->priv;
667
	struct sysfs_open_file *of;
668
	bool has_read, has_write, has_mmap;
669
	int error = -EACCES;
L
Linus Torvalds 已提交
670

671
	/* need attr_sd for attr and ops, its parent for kobj */
672
	if (!sysfs_get_active(attr_sd))
673
		return -ENODEV;
L
Linus Torvalds 已提交
674

675
	if (sysfs_is_bin(attr_sd)) {
676
		struct bin_attribute *battr = attr_sd->priv;
L
Linus Torvalds 已提交
677

678 679
		has_read = battr->read || battr->mmap;
		has_write = battr->write || battr->mmap;
680
		has_mmap = battr->mmap;
681 682
	} else {
		const struct sysfs_ops *ops = sysfs_file_ops(attr_sd);
L
Linus Torvalds 已提交
683

684 685 686 687
		/* every kobject with an attribute needs a ktype assigned */
		if (WARN(!ops, KERN_ERR
			 "missing sysfs attribute operations for kobject: %s\n",
			 kobject_name(kobj)))
688
			goto err_out;
689 690 691

		has_read = ops->show;
		has_write = ops->store;
692
		has_mmap = false;
L
Linus Torvalds 已提交
693 694
	}

695 696 697 698 699 700 701 702 703
	/* check perms and supported operations */
	if ((file->f_mode & FMODE_WRITE) &&
	    (!(inode->i_mode & S_IWUGO) || !has_write))
		goto err_out;

	if ((file->f_mode & FMODE_READ) &&
	    (!(inode->i_mode & S_IRUGO) || !has_read))
		goto err_out;

704
	/* allocate a sysfs_open_file for the file */
705
	error = -ENOMEM;
706 707
	of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL);
	if (!of)
708
		goto err_out;
L
Linus Torvalds 已提交
709

710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
	/*
	 * The following is done to give a different lockdep key to
	 * @of->mutex for files which implement mmap.  This is a rather
	 * crude way to avoid false positive lockdep warning around
	 * mm->mmap_sem - mmap nests @of->mutex under mm->mmap_sem and
	 * reading /sys/block/sda/trace/act_mask grabs sr_mutex, under
	 * which mm->mmap_sem nests, while holding @of->mutex.  As each
	 * open file has a separate mutex, it's okay as long as those don't
	 * happen on the same file.  At this point, we can't easily give
	 * each file a separate locking class.  Let's differentiate on
	 * whether the file has mmap or not for now.
	 */
	if (has_mmap)
		mutex_init(&of->mutex);
	else
		mutex_init(&of->mutex);

727 728
	of->sd = attr_sd;
	of->file = file;
729 730

	/*
731 732 733
	 * Always instantiate seq_file even if read access doesn't use
	 * seq_file or is not requested.  This unifies private data access
	 * and readable regular files are the vast majority anyway.
734
	 */
735
	if (sysfs_is_bin(attr_sd))
736
		error = seq_open(file, NULL);
737
	else
738
		error = seq_open(file, &kernfs_seq_ops);
739 740 741
	if (error)
		goto err_free;

742 743
	((struct seq_file *)file->private_data)->private = of;

744 745 746
	/* seq_file clears PWRITE unconditionally, restore it if WRITE */
	if (file->f_mode & FMODE_WRITE)
		file->f_mode |= FMODE_PWRITE;
747

T
Tejun Heo 已提交
748
	/* make sure we have open dirent struct */
749
	error = sysfs_get_open_dirent(attr_sd, of);
T
Tejun Heo 已提交
750
	if (error)
751
		goto err_close;
T
Tejun Heo 已提交
752

753
	/* open succeeded, put active references */
754
	sysfs_put_active(attr_sd);
755 756
	return 0;

757
err_close:
758
	seq_release(inode, file);
759
err_free:
760
	kfree(of);
761
err_out:
762
	sysfs_put_active(attr_sd);
L
Linus Torvalds 已提交
763 764 765
	return error;
}

T
Tejun Heo 已提交
766
static int sysfs_release(struct inode *inode, struct file *filp)
L
Linus Torvalds 已提交
767
{
T
Tejun Heo 已提交
768
	struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata;
769
	struct sysfs_open_file *of = sysfs_of(filp);
L
Linus Torvalds 已提交
770

771
	sysfs_put_open_dirent(sd, of);
772
	seq_release(inode, filp);
773
	kfree(of);
774

L
Linus Torvalds 已提交
775 776 777
	return 0;
}

778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803
void sysfs_unmap_bin_file(struct sysfs_dirent *sd)
{
	struct sysfs_open_dirent *od;
	struct sysfs_open_file *of;

	if (!sysfs_is_bin(sd))
		return;

	spin_lock_irq(&sysfs_open_dirent_lock);
	od = sd->s_attr.open;
	if (od)
		atomic_inc(&od->refcnt);
	spin_unlock_irq(&sysfs_open_dirent_lock);
	if (!od)
		return;

	mutex_lock(&sysfs_open_file_mutex);
	list_for_each_entry(of, &od->files, list) {
		struct inode *inode = file_inode(of->file);
		unmap_mapping_range(inode->i_mapping, 0, 0, 1);
	}
	mutex_unlock(&sysfs_open_file_mutex);

	sysfs_put_open_dirent(sd, NULL);
}

804 805 806 807 808 809 810
/* Sysfs attribute files are pollable.  The idea is that you read
 * the content and then you use 'poll' or 'select' to wait for
 * the content to change.  When the content changes (assuming the
 * manager for the kobject supports notification), poll will
 * return POLLERR|POLLPRI, and select will return the fd whether
 * it is waiting for read, write, or exceptions.
 * Once poll/select indicates that the value has changed, you
811
 * need to close and re-open the file, or seek to 0 and read again.
812 813
 * Reminder: this only works for attributes which actively support
 * it, and it is not possible to test an attribute from userspace
814
 * to see if it supports poll (Neither 'poll' nor 'select' return
815 816 817 818
 * an appropriate error code).  When in doubt, set a suitable timeout value.
 */
static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
{
819
	struct sysfs_open_file *of = sysfs_of(filp);
820
	struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
821
	struct sysfs_open_dirent *od = attr_sd->s_attr.open;
822 823

	/* need parent for the kobj, grab both */
824
	if (!sysfs_get_active(attr_sd))
825
		goto trigger;
826

827
	poll_wait(filp, &od->poll, wait);
828

829
	sysfs_put_active(attr_sd);
830

831
	if (of->event != atomic_read(&od->event))
832
		goto trigger;
833

834
	return DEFAULT_POLLMASK;
835 836

 trigger:
837
	return DEFAULT_POLLMASK|POLLERR|POLLPRI;
838 839
}

840 841 842
void sysfs_notify_dirent(struct sysfs_dirent *sd)
{
	struct sysfs_open_dirent *od;
843
	unsigned long flags;
844

845
	spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
846

847 848 849 850 851 852
	if (!WARN_ON(sysfs_type(sd) != SYSFS_KOBJ_ATTR)) {
		od = sd->s_attr.open;
		if (od) {
			atomic_inc(&od->event);
			wake_up_interruptible(&od->poll);
		}
853 854
	}

855
	spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
856 857 858
}
EXPORT_SYMBOL_GPL(sysfs_notify_dirent);

859
void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
860
{
861
	struct sysfs_dirent *sd = k->sd;
862

863 864 865
	mutex_lock(&sysfs_mutex);

	if (sd && dir)
T
Tejun Heo 已提交
866
		sd = sysfs_find_dirent(sd, dir, NULL);
867
	if (sd && attr)
T
Tejun Heo 已提交
868
		sd = sysfs_find_dirent(sd, attr, NULL);
869 870
	if (sd)
		sysfs_notify_dirent(sd);
871 872

	mutex_unlock(&sysfs_mutex);
873 874 875
}
EXPORT_SYMBOL_GPL(sysfs_notify);

876
const struct file_operations sysfs_file_operations = {
877
	.read		= kernfs_file_read,
878
	.write		= kernfs_file_write,
879
	.llseek		= generic_file_llseek,
L
Linus Torvalds 已提交
880 881
	.open		= sysfs_open_file,
	.release	= sysfs_release,
882
	.poll		= sysfs_poll,
L
Linus Torvalds 已提交
883 884
};

885
const struct file_operations sysfs_bin_operations = {
886
	.read		= kernfs_file_read,
887
	.write		= kernfs_file_write,
888
	.llseek		= generic_file_llseek,
889
	.mmap		= sysfs_bin_mmap,
890 891 892
	.open		= sysfs_open_file,
	.release	= sysfs_release,
	.poll		= sysfs_poll,
893 894
};

895 896 897
int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
			   const struct attribute *attr, int type,
			   umode_t amode, const void *ns)
L
Linus Torvalds 已提交
898
{
899
	umode_t mode = (amode & S_IALLUGO) | S_IFREG;
900
	struct sysfs_addrm_cxt acxt;
901
	struct sysfs_dirent *sd;
902
	int rc;
L
Linus Torvalds 已提交
903

904 905 906
	sd = sysfs_new_dirent(attr->name, mode, type);
	if (!sd)
		return -ENOMEM;
907 908

	sd->s_ns = ns;
909
	sd->priv = (void *)attr;
910
	sysfs_dirent_init_lockdep(sd);
L
Linus Torvalds 已提交
911

912 913
	sysfs_addrm_start(&acxt);
	rc = sysfs_add_one(&acxt, sd, dir_sd);
914
	sysfs_addrm_finish(&acxt);
915

916
	if (rc)
917
		sysfs_put(sd);
918

919
	return rc;
L
Linus Torvalds 已提交
920 921 922
}


923 924 925
int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
		   int type)
{
926
	return sysfs_add_file_mode_ns(dir_sd, attr, type, attr->mode, NULL);
927 928
}

L
Linus Torvalds 已提交
929
/**
930 931 932 933
 * sysfs_create_file_ns - create an attribute file for an object with custom ns
 * @kobj: object we're creating for
 * @attr: attribute descriptor
 * @ns: namespace the new file should belong to
L
Linus Torvalds 已提交
934
 */
935 936
int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr,
			 const void *ns)
L
Linus Torvalds 已提交
937
{
938
	BUG_ON(!kobj || !kobj->sd || !attr);
L
Linus Torvalds 已提交
939

940 941
	return sysfs_add_file_mode_ns(kobj->sd, attr, SYSFS_KOBJ_ATTR,
				      attr->mode, ns);
L
Linus Torvalds 已提交
942 943

}
944
EXPORT_SYMBOL_GPL(sysfs_create_file_ns);
L
Linus Torvalds 已提交
945

946 947 948 949 950 951 952 953 954 955 956 957
int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
{
	int err = 0;
	int i;

	for (i = 0; ptr[i] && !err; i++)
		err = sysfs_create_file(kobj, ptr[i]);
	if (err)
		while (--i >= 0)
			sysfs_remove_file(kobj, ptr[i]);
	return err;
}
958
EXPORT_SYMBOL_GPL(sysfs_create_files);
L
Linus Torvalds 已提交
959

960 961 962 963 964 965 966 967 968
/**
 * sysfs_add_file_to_group - add an attribute file to a pre-existing group.
 * @kobj: object we're acting for.
 * @attr: attribute descriptor.
 * @group: group name.
 */
int sysfs_add_file_to_group(struct kobject *kobj,
		const struct attribute *attr, const char *group)
{
969
	struct sysfs_dirent *dir_sd;
970 971
	int error;

972
	if (group)
T
Tejun Heo 已提交
973
		dir_sd = sysfs_get_dirent(kobj->sd, group);
974 975 976
	else
		dir_sd = sysfs_get(kobj->sd);

977 978 979 980 981 982
	if (!dir_sd)
		return -ENOENT;

	error = sysfs_add_file(dir_sd, attr, SYSFS_KOBJ_ATTR);
	sysfs_put(dir_sd);

983 984 985 986
	return error;
}
EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);

987 988 989 990 991 992 993
/**
 * sysfs_chmod_file - update the modified mode value on an object attribute.
 * @kobj: object we're acting for.
 * @attr: attribute descriptor.
 * @mode: file permissions.
 *
 */
994
int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
A
Al Viro 已提交
995
		     umode_t mode)
996
{
997
	struct sysfs_dirent *sd;
998
	struct iattr newattrs;
999 1000
	int rc;

1001
	sd = sysfs_get_dirent(kobj->sd, attr->name);
1002
	if (!sd)
1003
		return -ENOENT;
1004

1005
	newattrs.ia_mode = (mode & S_IALLUGO) | (sd->s_mode & ~S_IALLUGO);
1006
	newattrs.ia_valid = ATTR_MODE;
1007

1008 1009 1010
	rc = kernfs_setattr(sd, &newattrs);

	sysfs_put(sd);
1011
	return rc;
1012 1013 1014
}
EXPORT_SYMBOL_GPL(sysfs_chmod_file);

L
Linus Torvalds 已提交
1015
/**
1016 1017 1018 1019
 * sysfs_remove_file_ns - remove an object attribute with a custom ns tag
 * @kobj: object we're acting for
 * @attr: attribute descriptor
 * @ns: namespace tag of the file to remove
L
Linus Torvalds 已提交
1020
 *
1021
 * Hash the attribute name and namespace tag and kill the victim.
L
Linus Torvalds 已提交
1022
 */
1023 1024
void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
			  const void *ns)
L
Linus Torvalds 已提交
1025
{
1026
	struct sysfs_dirent *dir_sd = kobj->sd;
1027

1028
	kernfs_remove_by_name_ns(dir_sd, attr->name, ns);
L
Linus Torvalds 已提交
1029
}
1030
EXPORT_SYMBOL_GPL(sysfs_remove_file_ns);
L
Linus Torvalds 已提交
1031

1032
void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr)
1033 1034 1035 1036 1037
{
	int i;
	for (i = 0; ptr[i]; i++)
		sysfs_remove_file(kobj, ptr[i]);
}
1038
EXPORT_SYMBOL_GPL(sysfs_remove_files);
L
Linus Torvalds 已提交
1039

1040 1041 1042 1043 1044 1045 1046 1047 1048
/**
 * sysfs_remove_file_from_group - remove an attribute file from a group.
 * @kobj: object we're acting for.
 * @attr: attribute descriptor.
 * @group: group name.
 */
void sysfs_remove_file_from_group(struct kobject *kobj,
		const struct attribute *attr, const char *group)
{
1049
	struct sysfs_dirent *dir_sd;
1050

1051
	if (group)
T
Tejun Heo 已提交
1052
		dir_sd = sysfs_get_dirent(kobj->sd, group);
1053 1054
	else
		dir_sd = sysfs_get(kobj->sd);
1055
	if (dir_sd) {
1056
		kernfs_remove_by_name(dir_sd, attr->name);
1057
		sysfs_put(dir_sd);
1058 1059 1060 1061
	}
}
EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);

1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
/**
 *	sysfs_create_bin_file - create binary file for object.
 *	@kobj:	object.
 *	@attr:	attribute descriptor.
 */
int sysfs_create_bin_file(struct kobject *kobj,
			  const struct bin_attribute *attr)
{
	BUG_ON(!kobj || !kobj->sd || !attr);

	return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR);
}
EXPORT_SYMBOL_GPL(sysfs_create_bin_file);

/**
 *	sysfs_remove_bin_file - remove binary file for object.
 *	@kobj:	object.
 *	@attr:	attribute descriptor.
 */
void sysfs_remove_bin_file(struct kobject *kobj,
			   const struct bin_attribute *attr)
{
1084
	kernfs_remove_by_name(kobj->sd, attr->attr.name);
1085 1086 1087
}
EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);

1088
struct sysfs_schedule_callback_struct {
1089 1090
	struct list_head	workq_list;
	struct kobject		*kobj;
1091 1092
	void			(*func)(void *);
	void			*data;
1093
	struct module		*owner;
1094 1095 1096
	struct work_struct	work;
};

1097
static struct workqueue_struct *sysfs_workqueue;
1098 1099
static DEFINE_MUTEX(sysfs_workq_mutex);
static LIST_HEAD(sysfs_workq);
1100 1101 1102 1103 1104 1105 1106
static void sysfs_schedule_callback_work(struct work_struct *work)
{
	struct sysfs_schedule_callback_struct *ss = container_of(work,
			struct sysfs_schedule_callback_struct, work);

	(ss->func)(ss->data);
	kobject_put(ss->kobj);
1107
	module_put(ss->owner);
1108 1109 1110
	mutex_lock(&sysfs_workq_mutex);
	list_del(&ss->workq_list);
	mutex_unlock(&sysfs_workq_mutex);
1111 1112 1113 1114 1115 1116 1117 1118
	kfree(ss);
}

/**
 * sysfs_schedule_callback - helper to schedule a callback for a kobject
 * @kobj: object we're acting for.
 * @func: callback function to invoke later.
 * @data: argument to pass to @func.
1119
 * @owner: module owning the callback code
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
 *
 * sysfs attribute methods must not unregister themselves or their parent
 * kobject (which would amount to the same thing).  Attempts to do so will
 * deadlock, since unregistration is mutually exclusive with driver
 * callbacks.
 *
 * Instead methods can call this routine, which will attempt to allocate
 * and schedule a workqueue request to call back @func with @data as its
 * argument in the workqueue's process context.  @kobj will be pinned
 * until @func returns.
 *
 * Returns 0 if the request was submitted, -ENOMEM if storage could not
1132 1133
 * be allocated, -ENODEV if a reference to @owner isn't available,
 * -EAGAIN if a callback has already been scheduled for @kobj.
1134 1135
 */
int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
1136
		void *data, struct module *owner)
1137
{
1138
	struct sysfs_schedule_callback_struct *ss, *tmp;
1139

1140 1141
	if (!try_module_get(owner))
		return -ENODEV;
1142 1143 1144 1145

	mutex_lock(&sysfs_workq_mutex);
	list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list)
		if (ss->kobj == kobj) {
1146
			module_put(owner);
1147 1148 1149 1150 1151
			mutex_unlock(&sysfs_workq_mutex);
			return -EAGAIN;
		}
	mutex_unlock(&sysfs_workq_mutex);

1152
	if (sysfs_workqueue == NULL) {
1153
		sysfs_workqueue = create_singlethread_workqueue("sysfsd");
1154 1155 1156 1157 1158 1159
		if (sysfs_workqueue == NULL) {
			module_put(owner);
			return -ENOMEM;
		}
	}

1160
	ss = kmalloc(sizeof(*ss), GFP_KERNEL);
1161 1162
	if (!ss) {
		module_put(owner);
1163
		return -ENOMEM;
1164
	}
1165 1166 1167 1168
	kobject_get(kobj);
	ss->kobj = kobj;
	ss->func = func;
	ss->data = data;
1169
	ss->owner = owner;
1170
	INIT_WORK(&ss->work, sysfs_schedule_callback_work);
1171 1172 1173 1174
	INIT_LIST_HEAD(&ss->workq_list);
	mutex_lock(&sysfs_workq_mutex);
	list_add_tail(&ss->workq_list, &sysfs_workq);
	mutex_unlock(&sysfs_workq_mutex);
1175
	queue_work(sysfs_workqueue, &ss->work);
1176 1177 1178
	return 0;
}
EXPORT_SYMBOL_GPL(sysfs_schedule_callback);