]> git.hungrycats.org Git - linux/commitdiff
[PATCH] shift BKL out of notify_change
authorDave Hansen <haveblue@us.ibm.com>
Fri, 5 Apr 2002 07:13:11 +0000 (23:13 -0800)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Fri, 5 Apr 2002 07:13:11 +0000 (23:13 -0800)
Moved i_sem down into notify_change() and out of the UMSDOS
function. Moved BKL down from notify_change into filesystems.

17 files changed:
fs/adfs/inode.c
fs/affs/inode.c
fs/attr.c
fs/coda/inode.c
fs/fat/inode.c
fs/hfs/inode.c
fs/hpfs/inode.c
fs/inode.c
fs/intermezzo/dir.c
fs/jffs/inode-v23.c
fs/jffs2/file.c
fs/ncpfs/inode.c
fs/nfs/inode.c
fs/open.c
fs/reiserfs/file.c
fs/smbfs/inode.c
fs/umsdos/inode.c

index 660dc4b1638781425dc5c57d9a2877198bcfb8c7..8f7403772d0c2067f8b2036b9a19b57be5b549e0 100644 (file)
@@ -302,6 +302,8 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr)
        struct super_block *sb = inode->i_sb;
        unsigned int ia_valid = attr->ia_valid;
        int error;
+       
+       lock_kernel();
 
        error = inode_change_ok(inode, attr);
 
@@ -346,6 +348,7 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr)
        if (ia_valid & (ATTR_SIZE | ATTR_MTIME | ATTR_MODE))
                mark_inode_dirty(inode);
 out:
+       unlock_kernel();
        return error;
 }
 
index 2a75344cd54c6438abd07f256e4e4a950cdee4ec..39f18dc29465b315d89f11048d8fe6f0402653b7 100644 (file)
@@ -235,6 +235,8 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int error;
 
+       lock_kernel();
+
        pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid);
 
        error = inode_change_ok(inode,attr);
@@ -254,6 +256,7 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
        if (!error && (attr->ia_valid & ATTR_MODE))
                mode_to_prot(inode);
 out:
+       unlock_kernel();
        return error;
 }
 
index dc3d7c5dea1f72be5a44709d7309c2573e52b070..7909632a4704dbf73c732f9debb0678e4216c236 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -21,6 +21,8 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
        int retval = -EPERM;
        unsigned int ia_valid = attr->ia_valid;
 
+       lock_kernel();
+
        /* If force is set do it anyway. */
        if (ia_valid & ATTR_FORCE)
                goto fine;
@@ -55,6 +57,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
 fine:
        retval = 0;
 error:
+       unlock_kernel();
        return retval;
 }
 
@@ -62,7 +65,8 @@ int inode_setattr(struct inode * inode, struct iattr * attr)
 {
        unsigned int ia_valid = attr->ia_valid;
        int error = 0;
-
+       
+       lock_kernel();
        if (ia_valid & ATTR_SIZE) {
                error = vmtruncate(inode, attr->ia_size);
                if (error)
@@ -86,6 +90,7 @@ int inode_setattr(struct inode * inode, struct iattr * attr)
        }
        mark_inode_dirty(inode);
 out:
+       unlock_kernel();
        return error;
 }
 
@@ -127,7 +132,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
        if (!(ia_valid & ATTR_MTIME_SET))
                attr->ia_mtime = now;
 
-       lock_kernel();
+       down(&inode->i_sem);
        if (inode->i_op && inode->i_op->setattr) 
                error = inode->i_op->setattr(dentry, attr);
        else {
@@ -140,7 +145,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
                                error = inode_setattr(inode, attr);
                }
        }
-       unlock_kernel();
+       up(&inode->i_sem);
        if (!error) {
                unsigned long dn_mask = setattr_mask(ia_valid);
                if (dn_mask)
index c2c083b8e25573ee579c871ba231eaefb65eaf51..8a68f2a13461cb8bbd687b75b4b47f68d4c0ed5d 100644 (file)
@@ -258,6 +258,8 @@ int coda_notify_change(struct dentry *de, struct iattr *iattr)
         struct coda_vattr vattr;
         int error;
        
+       lock_kernel();
+       
         memset(&vattr, 0, sizeof(vattr)); 
 
        inode->i_ctime = CURRENT_TIME;
@@ -272,6 +274,8 @@ int coda_notify_change(struct dentry *de, struct iattr *iattr)
                coda_cache_clear_inode(inode);
        }
 
+       unlock_kernel();
+
        return error;
 }
 
index a8ce1db70a2c91e96639ee67a6f45b4de0874b73..724ca308f1a7a2025cb01f1ced2859eb7ed0f75e 100644 (file)
@@ -1054,17 +1054,24 @@ int fat_notify_change(struct dentry * dentry, struct iattr * attr)
 {
        struct super_block *sb = dentry->d_sb;
        struct inode *inode = dentry->d_inode;
-       int error;
+       int error = 0;
+
+       lock_kernel();
 
        /* FAT cannot truncate to a longer file */
        if (attr->ia_valid & ATTR_SIZE) {
-               if (attr->ia_size > inode->i_size)
-                       return -EPERM;
+               if (attr->ia_size > inode->i_size) {
+                       error = -EPERM;
+                       goto out;
+               }
        }
 
        error = inode_change_ok(inode, attr);
-       if (error)
-               return MSDOS_SB(sb)->options.quiet ? 0 : error;
+       if (error) {
+               if( MSDOS_SB(sb)->options.quiet )
+                   error = 0; 
+               goto out;
+       }
 
        if (((attr->ia_valid & ATTR_UID) && 
             (attr->ia_uid != MSDOS_SB(sb)->options.fs_uid)) ||
@@ -1074,12 +1081,13 @@ int fat_notify_change(struct dentry * dentry, struct iattr * attr)
             (attr->ia_mode & ~MSDOS_VALID_MODE)))
                error = -EPERM;
 
-       if (error)
-               return MSDOS_SB(sb)->options.quiet ? 0 : error;
-
-       error = inode_setattr(inode, attr);
-       if (error)
-               return error;
+       if (error) {
+               if( MSDOS_SB(sb)->options.quiet )  
+                       error = 0;
+               goto out;
+       }
+       if( error = inode_setattr(inode, attr) )
+               goto out;
 
        if (S_ISDIR(inode->i_mode))
                inode->i_mode |= S_IXUGO;
@@ -1087,6 +1095,8 @@ int fat_notify_change(struct dentry * dentry, struct iattr * attr)
        inode->i_mode = ((inode->i_mode & S_IFMT) | ((((inode->i_mode & S_IRWXU
            & ~MSDOS_SB(sb)->options.fs_umask) | S_IRUSR) >> 6)*S_IXUGO)) &
            ~MSDOS_SB(sb)->options.fs_umask;
-       return 0;
+out:
+       unlock_kernel();
+       return error;
 }
 MODULE_LICENSE("GPL");
index d4a78d00662c921fc477d23e3463b6bf8b082ba4..11cf9e8b2f4e5ed71b75ba6ab8d7d3fb39aaee44 100644 (file)
@@ -117,17 +117,18 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k
        struct hfs_cat_entry *entry = HFS_I(inode)->entry;
        struct dentry **de = entry->sys_entry;
        struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
-       int error, i;
+       int error=0, i;
+
+       lock_kernel();
 
        error = inode_change_ok(inode, attr); /* basic permission checks */
        if (error) {
                /* Let netatalk's afpd think chmod() always succeeds */
                if (hsb->s_afpd &&
                    (attr->ia_valid == (ATTR_MODE | ATTR_CTIME))) {
-                       return 0;
-               } else {
-                       return error;
+                       error = 0;
                }
+               goto out; 
        }
 
        /* no uig/gid changes and limit which mode bits can be set */
@@ -139,7 +140,10 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k
             (((entry->type == HFS_CDR_DIR) &&
               (attr->ia_mode != inode->i_mode))||
              (attr->ia_mode & ~HFS_VALID_MODE_BITS)))) {
-               return hsb->s_quiet ? 0 : error;
+               if( hsb->s_quiet ) { 
+                       error = 0;
+                       goto out;
+               }
        }
        
        if (entry->type == HFS_CDR_DIR) {
@@ -170,9 +174,9 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k
                }
        }
        error = inode_setattr(inode, attr);
-       if (error)
-               return error;
-
+       if (error) 
+               goto out;
+       
        /* We wouldn't want to mess with the sizes of the other fork */
        attr->ia_valid &= ~ATTR_SIZE;
 
@@ -204,7 +208,9 @@ static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int k
        }
        /* size changes handled in hfs_extent_adj() */
 
-       return 0;
+out:
+       unlock_kernel();
+       return error;
 }
 
 int hfs_notify_change(struct dentry *dentry, struct iattr * attr)
index c1411921e6da4addea03f6c8f56dea97ed106eb0..61578e25673e1bb5701d49c1237c95c194e44845 100644 (file)
@@ -303,15 +303,18 @@ void hpfs_write_inode_nolock(struct inode *i)
 int hpfs_notify_change(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = dentry->d_inode;
-       int error;
-       if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size) 
-               return -EINVAL;
-       if (inode->i_sb->s_hpfs_root == inode->i_ino) return -EINVAL;
-       if ((error = inode_change_ok(inode, attr))) return error;
-       error = inode_setattr(inode, attr);
-       if (error) return error;
-       hpfs_write_inode(inode);
-       return 0;
+       int error=0;
+       lock_kernel();
+       if ( ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size) ||
+            (inode->i_sb->s_hpfs_root == inode->i_ino) ) {
+               error = -EINVAL;
+       } else if ((error = inode_change_ok(inode, attr))) {
+       } else if ((error = inode_setattr(inode, attr))) {
+       } else {
+               hpfs_write_inode(inode);
+       }
+       unlock_kernel();
+       return error;
 }
 
 void hpfs_write_if_changed(struct inode *inode)
index cbe7d2eeb3498f0ea8c7542d72bd2d6bf54b31d7..745bba68b5be401a6009bec34e65c4d426a504fd 100644 (file)
@@ -143,6 +143,7 @@ void inode_init_once(struct inode *inode)
        INIT_LIST_HEAD(&inode->i_dirty_data_buffers);
        INIT_LIST_HEAD(&inode->i_devices);
        sema_init(&inode->i_sem, 1);
+       sema_init(&inode->i_attr_lock, 1);
        spin_lock_init(&inode->i_data.i_shared_lock);
        INIT_LIST_HEAD(&inode->i_data.i_mmap);
        INIT_LIST_HEAD(&inode->i_data.i_mmap_shared);
index de2d4afc07fbd57ac80a901798f5573483cea244..8fbd8f177dc17222e168a03e7a582864454d6145 100644 (file)
@@ -282,11 +282,13 @@ int presto_setattr(struct dentry *de, struct iattr *iattr)
         struct presto_file_set *fset;
         struct lento_vfs_context info = { 0, 0, 0 };
 
+       lock_kernel();  
+
         ENTRY;
         error = presto_prep(de, &cache, &fset);
         if ( error ) {
                 EXIT;
-                return error;
+                goto out;        
         }
 
         if (!iattr->ia_valid)
@@ -300,7 +302,8 @@ int presto_setattr(struct dentry *de, struct iattr *iattr)
         
         if ( presto_get_permit(de->d_inode) < 0 ) {
                 EXIT;
-                return -EROFS;
+                error = -EROFS;
+                goto out;
         }
 
         if (!ISLENTO(presto_c2m(cache)))
@@ -308,6 +311,8 @@ int presto_setattr(struct dentry *de, struct iattr *iattr)
        info.flags |= LENTO_FL_IGNORE_TIME;
         error = presto_do_setattr(fset, de, iattr, &info);
         presto_put_permit(de->d_inode);
+out:
+        unlock_kernel();
         return error;
 }
 
index 33ef462c39ffc85f1236d982756ea9f2c217cc62..9bcd5bdd18a67506fccc09f97b47387566ed3560 100644 (file)
@@ -196,11 +196,13 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
        struct jffs_file *f;
        struct jffs_node *new_node;
        int update_all;
-       int res;
+       int res = 0;
        int recoverable = 0;
 
-       if ((res = inode_change_ok(inode, iattr)))
-               return res;
+       lock_kernel();
+
+       if ((res = inode_change_ok(inode, iattr))) 
+               goto out;
 
        c = (struct jffs_control *)inode->i_sb->u.generic_sbp;
        fmc = c->fmc;
@@ -215,7 +217,8 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
                       inode->i_ino);
                D3(printk (KERN_NOTICE "notify_change(): up biglock\n"));
                up(&fmc->biglock);
-               return -EINVAL;
+               res = -EINVAL;
+               goto out;
        });
 
        D1(printk("***jffs_setattr(): file: \"%s\", ino: %u\n",
@@ -235,7 +238,8 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
                D(printk("jffs_setattr(): Allocation failed!\n"));
                D3(printk (KERN_NOTICE "notify_change(): up biglock\n"));
                up(&fmc->biglock);
-               return -ENOMEM;
+               res = -ENOMEM;
+               goto out;
        }
 
        new_node->data_offset = 0;
@@ -321,7 +325,7 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
                jffs_free_node(new_node);
                D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
                up(&c->fmc->biglock);
-               return res;
+               goto out;
        }
 
        jffs_insert_node(c, f, &raw_inode, 0, new_node);
@@ -329,7 +333,9 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
        mark_inode_dirty(inode);
        D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
        up(&c->fmc->biglock);
-       return 0;
+out:
+       unlock_kernel();
+       return res;
 } /* jffs_notify_change()  */
 
 
index 5106a666506194bd85322601b4f677c073eb9272..404c8b63cb9ac4052903d09336f0a7b2b4b28cdc 100644 (file)
@@ -109,11 +109,12 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
        int mdatalen = 0;
        unsigned int ivalid;
        uint32_t phys_ofs, alloclen;
-       int ret;
+       int ret = 0;
+       lock_kernel();
        D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
        ret = inode_change_ok(inode, iattr);
        if (ret) 
-               return ret;
+               goto out;
 
        /* Special cases - we don't want more than one data node
           for these types on the medium at any time. So setattr
@@ -130,12 +131,14 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
        } else if (S_ISLNK(inode->i_mode)) {
                mdatalen = f->metadata->size;
                mdata = kmalloc(f->metadata->size, GFP_USER);
-               if (!mdata)
-                       return -ENOMEM;
+               if (!mdata) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
                ret = jffs2_read_dnode(c, f->metadata, mdata, 0, mdatalen);
                if (ret) {
                        kfree(mdata);
-                       return ret;
+                       goto out;
                }
                D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
        }
@@ -144,7 +147,8 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
        if (!ri) {
                if (S_ISLNK(inode->i_mode))
                        kfree(mdata);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto out;
        }
                
        ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL);
@@ -152,7 +156,7 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
                jffs2_free_raw_inode(ri);
                if (S_ISLNK(inode->i_mode & S_IFMT))
                         kfree(mdata);
-               return ret;
+               goto out;
        }
        down(&f->sem);
        ivalid = iattr->ia_valid;
@@ -201,7 +205,8 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
                jffs2_complete_reservation(c);
                jffs2_free_raw_inode(ri);
                up(&f->sem);
-               return PTR_ERR(new_metadata);
+               ret = PTR_ERR(new_metadata);
+               goto out;
        }
        /* It worked. Update the inode */
        inode->i_atime = ri->atime;
@@ -235,7 +240,9 @@ int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
        up(&f->sem);
        jffs2_complete_reservation(c);
 
-       return 0;
+out:
+       unlock_kernel();        
+       return ret;
 }
 
 int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)
index 0875bfe5bd8c70280a9e6d1665710b394b854672..d3cfbf5f929fe1c3c77c2ae1838518a11f2e7f9c 100644 (file)
@@ -592,6 +592,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
 
        result = -EIO;
 
+       lock_kernel();  
+
        server = NCP_SERVER(inode);
        if ((!server) || !ncp_conn_valid(server))
                goto out;
@@ -636,7 +638,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
                                info.attributes |=  (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
                 } else if (!S_ISREG(inode->i_mode))
                 {
-                        return -EPERM;
+                       result = -EPERM;
+                       goto out;
                 }
                 else
                 {
@@ -722,7 +725,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
                        attr->ia_size);
 
                if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
-                       return -EACCES;
+                       result = -EACCES;
+                       goto out;
                }
                ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
                          attr->ia_size, 0, "", &written);
@@ -735,6 +739,7 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
                        result = vmtruncate(inode, attr->ia_size);
        }
 out:
+       unlock_kernel();
        return result;
 }
 
index ea038439ae140de1f6780700db626ec9a1e4af12..5b61dcdc0d248bc2b50b27e1f78df661b2e609da 100644 (file)
@@ -733,6 +733,8 @@ nfs_notify_change(struct dentry *dentry, struct iattr *attr)
        struct nfs_fattr fattr;
        int error;
 
+       lock_kernel();
+
        /*
         * Make sure the inode is up-to-date.
         */
@@ -781,6 +783,7 @@ printk("nfs_notify_change: revalidate failed, error=%d\n", error);
        NFS_CACHEINV(inode);
        error = nfs_refresh_inode(inode, &fattr);
 out:
+       unlock_kernel();
        return error;
 }
 
index 7387c05384df4c8540e06ed6ab53c6089f54f83e..c6db81686f2b30d257eb1bfb6bd3ddbc0c7d5a64 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -81,11 +81,9 @@ int do_truncate(struct dentry *dentry, loff_t length)
        if (length < 0)
                return -EINVAL;
 
-       down(&inode->i_sem);
        newattrs.ia_size = length;
        newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
        error = notify_change(dentry, &newattrs);
-       up(&inode->i_sem);
        return error;
 }
 
index cc9c874bd9647ccd2f890fe7cba8fbc74c4171c2..75d41a57c53829b9d746d087a15bf461438ba296 100644 (file)
@@ -95,14 +95,16 @@ static int reiserfs_sync_file(
 static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
     struct inode *inode = dentry->d_inode ;
     int error ;
+    lock_kernel();
     if (attr->ia_valid & ATTR_SIZE) {
        /* version 2 items will be caught by the s_maxbytes check
        ** done for us in vmtruncate
        */
        if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
-           attr->ia_size > MAX_NON_LFS)
-            return -EFBIG ;
-
+           attr->ia_size > MAX_NON_LFS) {
+           error = -EFBIG ;
+           goto out;
+       }
        /* fill in hole pointers in the expanding truncate case. */
         if (attr->ia_size > inode->i_size) {
            error = generic_cont_expand(inode, attr->ia_size) ;
@@ -114,20 +116,24 @@ static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
                journal_end(&th, inode->i_sb, 4) ;
            }
            if (error)
-               return error ;
+               goto out;
        }
     }
 
     if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
         ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
-       (get_inode_sd_version (inode) == STAT_DATA_V1))
+       (get_inode_sd_version (inode) == STAT_DATA_V1)) {
                /* stat data of format v3.5 has 16 bit uid and gid */
-           return -EINVAL;
+           error = -EINVAL;
+           goto out;   
+       }
 
     error = inode_change_ok(inode, attr) ;
     if (!error)
         inode_setattr(inode, attr) ;
 
+out:
+    unlock_kernel();
     return error ;
 }
 
index a3426d6a0ddc1d52f8eae553bfffb2d0db231c5d..01cc883148b259a1096eeb34e249fb2e6cba4ef9 100644 (file)
@@ -621,6 +621,8 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr)
        int error, changed, refresh = 0;
        struct smb_fattr fattr;
 
+       lock_kernel();
+
        error = smb_revalidate_inode(dentry);
        if (error)
                goto out;
@@ -714,6 +716,7 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr)
 out:
        if (refresh)
                smb_refresh_inode(dentry);
+       unlock_kernel();
        return error;
 }
 
index fbd0b9f3ed28e33000330ade622351c832847888..79b5bb2eacda14769663f2f8c91e889b731aa9c8 100644 (file)
@@ -165,6 +165,8 @@ int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
        struct dentry *temp, *old_dentry = NULL;
        int ret;
 
+       lock_kernel();
+
        ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len,
                                &info);
        if (ret)
@@ -208,14 +210,13 @@ dentry->d_parent->d_name.name, dentry->d_name.name, info.fake.fname));
        if (ret)
                goto out;
 
-       down(&dir->i_sem);
        ret = umsdos_notify_change_locked(dentry, attr);
-       up(&dir->i_sem);
        if (ret == 0)
                ret = inode_setattr (inode, attr);
 out:
        if (old_dentry)
                dput (dentry);  /* if we had to use fake dentry for hardlinks, dput() it now */
+       unlock_kernel();
        return ret;
 }