Merge git://www.linux-watchdog.org/linux-watchdog
[cascardo/linux.git] / fs / proc / generic.c
index 0d80cef..e064f56 100644 (file)
@@ -261,16 +261,9 @@ static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
        if (error)
                return error;
 
-       if ((iattr->ia_valid & ATTR_SIZE) &&
-           iattr->ia_size != i_size_read(inode)) {
-               error = vmtruncate(inode, iattr->ia_size);
-               if (error)
-                       return error;
-       }
-
        setattr_copy(inode, iattr);
        mark_inode_dirty(inode);
-       
+
        de->uid = inode->i_uid;
        de->gid = inode->i_gid;
        de->mode = inode->i_mode;
@@ -350,37 +343,38 @@ static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */
  * Return an inode number between PROC_DYNAMIC_FIRST and
  * 0xffffffff, or zero on failure.
  */
-static unsigned int get_inode_number(void)
+int proc_alloc_inum(unsigned int *inum)
 {
        unsigned int i;
        int error;
 
 retry:
-       if (ida_pre_get(&proc_inum_ida, GFP_KERNEL) == 0)
-               return 0;
+       if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL))
+               return -ENOMEM;
 
-       spin_lock(&proc_inum_lock);
+       spin_lock_bh(&proc_inum_lock);
        error = ida_get_new(&proc_inum_ida, &i);
-       spin_unlock(&proc_inum_lock);
+       spin_unlock_bh(&proc_inum_lock);
        if (error == -EAGAIN)
                goto retry;
        else if (error)
-               return 0;
+               return error;
 
        if (i > UINT_MAX - PROC_DYNAMIC_FIRST) {
-               spin_lock(&proc_inum_lock);
+               spin_lock_bh(&proc_inum_lock);
                ida_remove(&proc_inum_ida, i);
-               spin_unlock(&proc_inum_lock);
-               return 0;
+               spin_unlock_bh(&proc_inum_lock);
+               return -ENOSPC;
        }
-       return PROC_DYNAMIC_FIRST + i;
+       *inum = PROC_DYNAMIC_FIRST + i;
+       return 0;
 }
 
-static void release_inode_number(unsigned int inum)
+void proc_free_inum(unsigned int inum)
 {
-       spin_lock(&proc_inum_lock);
+       spin_lock_bh(&proc_inum_lock);
        ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST);
-       spin_unlock(&proc_inum_lock);
+       spin_unlock_bh(&proc_inum_lock);
 }
 
 static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd)
@@ -554,13 +548,12 @@ static const struct inode_operations proc_dir_inode_operations = {
 
 static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
 {
-       unsigned int i;
        struct proc_dir_entry *tmp;
+       int ret;
        
-       i = get_inode_number();
-       if (i == 0)
-               return -EAGAIN;
-       dp->low_ino = i;
+       ret = proc_alloc_inum(&dp->low_ino);
+       if (ret)
+               return ret;
 
        if (S_ISDIR(dp->mode)) {
                if (dp->proc_iops == NULL) {
@@ -764,7 +757,7 @@ EXPORT_SYMBOL(proc_create_data);
 
 static void free_proc_entry(struct proc_dir_entry *de)
 {
-       release_inode_number(de->low_ino);
+       proc_free_inum(de->low_ino);
 
        if (S_ISLNK(de->mode))
                kfree(de->data);