diff options
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r-- | fs/proc/generic.c | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 0d80cef4cfb9..76ddae83daa5 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -261,16 +261,9 @@ static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) | |||
261 | if (error) | 261 | if (error) |
262 | return error; | 262 | return error; |
263 | 263 | ||
264 | if ((iattr->ia_valid & ATTR_SIZE) && | ||
265 | iattr->ia_size != i_size_read(inode)) { | ||
266 | error = vmtruncate(inode, iattr->ia_size); | ||
267 | if (error) | ||
268 | return error; | ||
269 | } | ||
270 | |||
271 | setattr_copy(inode, iattr); | 264 | setattr_copy(inode, iattr); |
272 | mark_inode_dirty(inode); | 265 | mark_inode_dirty(inode); |
273 | 266 | ||
274 | de->uid = inode->i_uid; | 267 | de->uid = inode->i_uid; |
275 | de->gid = inode->i_gid; | 268 | de->gid = inode->i_gid; |
276 | de->mode = inode->i_mode; | 269 | de->mode = inode->i_mode; |
@@ -350,37 +343,39 @@ static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */ | |||
350 | * Return an inode number between PROC_DYNAMIC_FIRST and | 343 | * Return an inode number between PROC_DYNAMIC_FIRST and |
351 | * 0xffffffff, or zero on failure. | 344 | * 0xffffffff, or zero on failure. |
352 | */ | 345 | */ |
353 | static unsigned int get_inode_number(void) | 346 | int proc_alloc_inum(unsigned int *inum) |
354 | { | 347 | { |
355 | unsigned int i; | 348 | unsigned int i; |
356 | int error; | 349 | int error; |
357 | 350 | ||
358 | retry: | 351 | retry: |
359 | if (ida_pre_get(&proc_inum_ida, GFP_KERNEL) == 0) | 352 | if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL)) |
360 | return 0; | 353 | return -ENOMEM; |
361 | 354 | ||
362 | spin_lock(&proc_inum_lock); | 355 | spin_lock_irq(&proc_inum_lock); |
363 | error = ida_get_new(&proc_inum_ida, &i); | 356 | error = ida_get_new(&proc_inum_ida, &i); |
364 | spin_unlock(&proc_inum_lock); | 357 | spin_unlock_irq(&proc_inum_lock); |
365 | if (error == -EAGAIN) | 358 | if (error == -EAGAIN) |
366 | goto retry; | 359 | goto retry; |
367 | else if (error) | 360 | else if (error) |
368 | return 0; | 361 | return error; |
369 | 362 | ||
370 | if (i > UINT_MAX - PROC_DYNAMIC_FIRST) { | 363 | if (i > UINT_MAX - PROC_DYNAMIC_FIRST) { |
371 | spin_lock(&proc_inum_lock); | 364 | spin_lock_irq(&proc_inum_lock); |
372 | ida_remove(&proc_inum_ida, i); | 365 | ida_remove(&proc_inum_ida, i); |
373 | spin_unlock(&proc_inum_lock); | 366 | spin_unlock_irq(&proc_inum_lock); |
374 | return 0; | 367 | return -ENOSPC; |
375 | } | 368 | } |
376 | return PROC_DYNAMIC_FIRST + i; | 369 | *inum = PROC_DYNAMIC_FIRST + i; |
370 | return 0; | ||
377 | } | 371 | } |
378 | 372 | ||
379 | static void release_inode_number(unsigned int inum) | 373 | void proc_free_inum(unsigned int inum) |
380 | { | 374 | { |
381 | spin_lock(&proc_inum_lock); | 375 | unsigned long flags; |
376 | spin_lock_irqsave(&proc_inum_lock, flags); | ||
382 | ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST); | 377 | ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST); |
383 | spin_unlock(&proc_inum_lock); | 378 | spin_unlock_irqrestore(&proc_inum_lock, flags); |
384 | } | 379 | } |
385 | 380 | ||
386 | static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd) | 381 | static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd) |
@@ -554,13 +549,12 @@ static const struct inode_operations proc_dir_inode_operations = { | |||
554 | 549 | ||
555 | static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp) | 550 | static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp) |
556 | { | 551 | { |
557 | unsigned int i; | ||
558 | struct proc_dir_entry *tmp; | 552 | struct proc_dir_entry *tmp; |
553 | int ret; | ||
559 | 554 | ||
560 | i = get_inode_number(); | 555 | ret = proc_alloc_inum(&dp->low_ino); |
561 | if (i == 0) | 556 | if (ret) |
562 | return -EAGAIN; | 557 | return ret; |
563 | dp->low_ino = i; | ||
564 | 558 | ||
565 | if (S_ISDIR(dp->mode)) { | 559 | if (S_ISDIR(dp->mode)) { |
566 | if (dp->proc_iops == NULL) { | 560 | if (dp->proc_iops == NULL) { |
@@ -764,7 +758,7 @@ EXPORT_SYMBOL(proc_create_data); | |||
764 | 758 | ||
765 | static void free_proc_entry(struct proc_dir_entry *de) | 759 | static void free_proc_entry(struct proc_dir_entry *de) |
766 | { | 760 | { |
767 | release_inode_number(de->low_ino); | 761 | proc_free_inum(de->low_ino); |
768 | 762 | ||
769 | if (S_ISLNK(de->mode)) | 763 | if (S_ISLNK(de->mode)) |
770 | kfree(de->data); | 764 | kfree(de->data); |