X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=fs%2Fjffs2%2Ffs.c;h=e26ea78c7892f7a4f157819a06e052add03057fd;hb=cf816ecb533ab96b883dfdc0db174598b5b5c4d2;hp=ed85f9afdbc8ae4dfb5c65541c89a526d9a6f400;hpb=fb9fc395174138983a49f2da982ed14caabbe741;p=linux-2.6-omap-h63xx.git diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index ed85f9afdbc..e26ea78c789 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -97,11 +97,7 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid); if (ivalid & ATTR_MODE) - if (iattr->ia_mode & S_ISGID && - !in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID)) - ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID); - else - ri->mode = cpu_to_jemode(iattr->ia_mode); + ri->mode = cpu_to_jemode(iattr->ia_mode); else ri->mode = cpu_to_jemode(inode->i_mode); @@ -230,16 +226,23 @@ void jffs2_clear_inode (struct inode *inode) jffs2_do_clear_inode(c, f); } -void jffs2_read_inode (struct inode *inode) +struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) { struct jffs2_inode_info *f; struct jffs2_sb_info *c; struct jffs2_raw_inode latest_node; union jffs2_device_node jdev; + struct inode *inode; dev_t rdev = 0; int ret; - D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino)); + D1(printk(KERN_DEBUG "jffs2_iget(): ino == %lu\n", ino)); + + inode = iget_locked(sb, ino); + if (!inode) + return ERR_PTR(-ENOMEM); + if (!(inode->i_state & I_NEW)) + return inode; f = JFFS2_INODE_INFO(inode); c = JFFS2_SB_INFO(inode->i_sb); @@ -250,9 +253,9 @@ void jffs2_read_inode (struct inode *inode) ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); if (ret) { - make_bad_inode(inode); up(&f->sem); - return; + iget_failed(inode); + return ERR_PTR(ret); } inode->i_mode = jemode_to_cpu(latest_node.mode); inode->i_uid = je16_to_cpu(latest_node.uid); @@ -303,19 +306,14 @@ void jffs2_read_inode (struct inode *inode) if (f->metadata->size != sizeof(jdev.old) && f->metadata->size != sizeof(jdev.new)) { printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size); - up(&f->sem); - jffs2_do_clear_inode(c, f); - make_bad_inode(inode); - return; + goto error_io; } D1(printk(KERN_DEBUG "Reading device numbers from flash\n")); - if (jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size) < 0) { + ret = jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size); + if (ret < 0) { /* Eep */ printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino); - up(&f->sem); - jffs2_do_clear_inode(c, f); - make_bad_inode(inode); - return; + goto error; } if (f->metadata->size == sizeof(jdev.old)) rdev = old_decode_dev(je16_to_cpu(jdev.old)); @@ -335,6 +333,16 @@ void jffs2_read_inode (struct inode *inode) up(&f->sem); D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n")); + unlock_new_inode(inode); + return inode; + +error_io: + ret = -EIO; +error: + up(&f->sem); + jffs2_do_clear_inode(c, f); + iget_failed(inode); + return ERR_PTR(ret); } void jffs2_dirty_inode(struct inode *inode) @@ -402,8 +410,7 @@ void jffs2_write_super (struct super_block *sb) /* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, fill in the raw_inode while you're at it. */ -struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri, - struct posix_acl **acl) +struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri) { struct inode *inode; struct super_block *sb = dir_i->i_sb; @@ -438,19 +445,11 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i /* POSIX ACLs have to be processed now, at least partly. The umask is only applied if there's no default ACL */ - if (!S_ISLNK(mode)) { - *acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT); - if (IS_ERR(*acl)) { - make_bad_inode(inode); - iput(inode); - inode = (void *)*acl; - *acl = NULL; - return inode; - } - if (!(*acl)) - mode &= ~current->fs->umask; - } else { - *acl = NULL; + ret = jffs2_init_acl_pre(dir_i, inode, &mode); + if (ret) { + make_bad_inode(inode); + iput(inode); + return ERR_PTR(ret); } ret = jffs2_do_new_inode (c, f, mode, ri); if (ret) { @@ -531,15 +530,16 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) if ((ret = jffs2_do_mount_fs(c))) goto out_inohash; - ret = -EINVAL; - D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n")); - root_i = iget(sb, 1); - if (is_bad_inode(root_i)) { + root_i = jffs2_iget(sb, 1); + if (IS_ERR(root_i)) { D1(printk(KERN_WARNING "get root inode failed\n")); - goto out_root_i; + ret = PTR_ERR(root_i); + goto out_root; } + ret = -ENOMEM; + D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n")); sb->s_root = d_alloc_root(root_i); if (!sb->s_root) @@ -555,6 +555,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) out_root_i: iput(root_i); +out_root: jffs2_free_ino_caches(c); jffs2_free_raw_node_refs(c); if (jffs2_blocks_use_vmalloc(c)) @@ -624,9 +625,9 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, jffs2_do_unlink() would need the alloc_sem and we have it. Just iget() it, and if read_inode() is necessary that's OK. */ - inode = iget(OFNI_BS_2SFFJ(c), inum); - if (!inode) - return ERR_PTR(-ENOMEM); + inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum); + if (IS_ERR(inode)) + return ERR_CAST(inode); } if (is_bad_inode(inode)) { printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n",