X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Freiserfs%2Fioctl.c;h=0e225be224b3b534b703968c828647e818d3e6c0;hb=d46bc780027c5439db9f72d42c0732775b53925a;hp=ec59e074416accafa7347afba4b8f1273b64e1a9;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index ec59e0744..0e225be22 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c @@ -20,7 +20,7 @@ int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg) { - unsigned int flags; + unsigned int flags, oldflags; switch (cmd) { case REISERFS_IOC_UNPACK: @@ -36,6 +36,7 @@ int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, case REISERFS_IOC_GETFLAGS: flags = REISERFS_I(inode) -> i_attrs; i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags ); + flags &= REISERFS_FL_USER_VISIBLE; return put_user(flags, (int *) arg); case REISERFS_IOC_SETFLAGS: { if (IS_RDONLY(inode)) @@ -47,8 +48,10 @@ int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, if (get_user(flags, (int *) arg)) return -EFAULT; - if ( ( ( flags ^ REISERFS_I(inode) -> i_attrs) & ( REISERFS_IMMUTABLE_FL | REISERFS_APPEND_FL)) && - !capable( CAP_LINUX_IMMUTABLE ) ) + oldflags = REISERFS_I(inode) -> i_attrs; + if ( (oldflags & REISERFS_IMMUTABLE_FL) || ( ( (flags ^ oldflags) & + (REISERFS_IMMUTABLE_FL | REISERFS_IUNLINK_FL | REISERFS_APPEND_FL)) && + !capable( CAP_LINUX_IMMUTABLE ) ) ) return -EPERM; if( ( flags & REISERFS_NOTAIL_FL ) && @@ -59,6 +62,9 @@ int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, if( result ) return result; } + + flags = flags & REISERFS_FL_USER_MODIFYABLE; + flags |= oldflags & ~REISERFS_FL_USER_MODIFYABLE; sd_attrs_to_i_attrs( flags, inode ); REISERFS_I(inode) -> i_attrs = flags; inode->i_ctime = CURRENT_TIME;