+int reiserfs_setattr_flags(struct inode *inode, unsigned int flags)
+{
+ unsigned int oldflags, newflags;
+
+ oldflags = REISERFS_I(inode)->i_flags;
+ newflags = oldflags & ~(REISERFS_IMMUTABLE_FL |
+ REISERFS_IUNLINK_FL | REISERFS_BARRIER_FL);
+ if (flags & ATTR_FLAG_IMMUTABLE)
+ newflags |= REISERFS_IMMUTABLE_FL;
+ if (flags & ATTR_FLAG_IUNLINK)
+ newflags |= REISERFS_IUNLINK_FL;
+ if (flags & ATTR_FLAG_BARRIER)
+ newflags |= REISERFS_BARRIER_FL;
+
+ if (oldflags ^ newflags) {
+ REISERFS_I(inode)->i_flags = newflags;
+ inode->i_ctime = CURRENT_TIME;
+ }
+ return 0;
+}
+
+int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
+ struct inode *inode = dentry->d_inode ;
+ int error ;
+ unsigned int ia_valid = attr->ia_valid;
+ reiserfs_write_lock(inode->i_sb);
+ 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) {
+ 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) ;
+ if (REISERFS_I(inode)->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)
+ 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)) {
+ /* stat data of format v3.5 has 16 bit uid and gid */
+ error = -EINVAL;
+ goto out;
+ }
+
+ error = inode_change_ok(inode, attr) ;
+
+ if (!error && attr->ia_valid & ATTR_ATTR_FLAG)
+ reiserfs_setattr_flags(inode, attr->ia_attr_flags);
+
+ if (!error) {
+ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
+ error = reiserfs_chown_xattrs (inode, attr);
+
+ if (!error)
+ error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
+ }
+ if (!error)
+ error = inode_setattr(inode, attr) ;
+ }
+
+
+ if (!error && reiserfs_posixacl (inode->i_sb)) {
+ if (attr->ia_valid & ATTR_MODE)
+ error = reiserfs_acl_chmod (inode);
+ }
+
+out:
+ reiserfs_write_unlock(inode->i_sb);
+ return error ;
+}
+
+