Esempio n. 1
0
static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
    struct inode *inode = dentry->d_inode ;
    int error ;
    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 ;

	/* fill in hole pointers in the expanding truncate case. */
        if (attr->ia_size > inode->i_size) {
	    error = generic_cont_expand(inode, attr->ia_size) ;
	    if (inode->u.reiserfs_i.i_prealloc_count > 0) {
		struct reiserfs_transaction_handle th ;
		/* we're changing at most 2 bitmaps, inode + super */
		journal_begin(&th, inode->i_sb, 4) ;
		reiserfs_discard_prealloc (&th, inode);
		journal_end(&th, inode->i_sb, 4) ;
	    }
	    if (error)
	        return error ;
	}
    }

    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))
		/* stat data of format v3.5 has 16 bit uid and gid */
	    return -EINVAL;

    error = inode_change_ok(inode, attr) ;
    if (!error)
        inode_setattr(inode, attr) ;

    return error ;
}
Esempio n. 2
0
static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
    struct inode *inode = dentry->d_inode ;
    int error ;
    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 ;

	/* fill in hole pointers in the expanding truncate case. */
        if (attr->ia_size > inode->i_size) {
	    error = generic_cont_expand(inode, attr->ia_size) ;
	    if (inode->u.reiserfs_i.i_prealloc_count > 0) {
		struct reiserfs_transaction_handle th ;
		/* we're changing at most 2 bitmaps, inode + super */
		journal_begin(&th, inode->i_sb, 4) ;
		reiserfs_discard_prealloc (&th, inode);
		journal_end(&th, inode->i_sb, 4) ;
	    }
	    if (error)
	        return error ;
	}
    }

    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))
		/* stat data of format v3.5 has 16 bit uid and gid */
	    return -EINVAL;

#ifdef CONFIG_REISERFS_IMMUTABLE_HACK 
    if (reiserfs_suid_immutable(inode->i_sb)) {
	uid_t uid;
	umode_t mode;

	uid = (attr->ia_valid & ATTR_UID) ? attr->ia_uid : inode->i_uid;
	mode = (attr->ia_valid & ATTR_MODE) ? attr->ia_mode : inode->i_mode;
	if (uid == 0 && (mode & S_ISUID) && !capable(CAP_LINUX_IMMUTABLE))
	    return -EPERM;
    }
#endif /* COCONFIG_REISERFS_IMMUTABLE_HACK */

    error = inode_change_ok(inode, attr) ;
#ifdef CONFIG_REISERFS_IMMUTABLE_HACK 
    if (!error && reiserfs_suid_immutable(inode->i_sb)) {
	uid_t uid;
	umode_t mode;

	uid = (attr->ia_valid & ATTR_UID) ? attr->ia_uid : inode->i_uid;
	mode = (attr->ia_valid & ATTR_MODE) ? attr->ia_mode : inode->i_mode;
	inode->i_flags &= ~S_IMMUTABLE;
	if (uid == 0 && (mode & S_ISUID)) {
	    inode->i_flags |= S_IMMUTABLE;
#ifdef CONFIG_REISERFS_IMMUTABLE_HACK_DEBUG 
	    printk("set IMMUTABLE, inode %p\n", inode); 
#endif /* CONFIG_REISERFS_IMMUTABLE_HACK_DEBUG */ 
	}
    }
#endif /* COCONFIG_REISERFS_IMMUTABLE_HACK */
    if (!error)
        inode_setattr(inode, attr) ;

    return error ;
}