2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
6 #include <linux/reiserfs_fs.h>
7 #include <linux/time.h>
8 #include <asm/uaccess.h>
9 #include <linux/pagemap.h>
10 #include <linux/smp_lock.h>
13 ** reiserfs_ioctl - handler for ioctl for inode
14 ** supported commands:
15 ** 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
16 ** and prevent packing file (argument arg has to be non-zero)
17 ** 2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
18 ** 3) That's all for a while ...
20 int reiserfs_ioctl (struct inode
* inode
, struct file
* filp
, unsigned int cmd
,
26 case REISERFS_IOC_UNPACK
:
27 if( S_ISREG( inode
-> i_mode
) ) {
29 return reiserfs_unpack (inode
, filp
);
34 /* following two cases are taken from fs/ext2/ioctl.c by Remy
35 Card (card@masi.ibp.fr) */
36 case REISERFS_IOC_GETFLAGS
:
37 flags
= REISERFS_I(inode
) -> i_attrs
;
38 i_attrs_to_sd_attrs( inode
, ( __u16
* ) &flags
);
39 return put_user(flags
, (int __user
*) arg
);
40 case REISERFS_IOC_SETFLAGS
: {
44 if ((current
->fsuid
!= inode
->i_uid
) && !capable(CAP_FOWNER
))
47 if (get_user(flags
, (int __user
*) arg
))
50 if ( ( ( flags
^ REISERFS_I(inode
) -> i_attrs
) & ( REISERFS_IMMUTABLE_FL
| REISERFS_APPEND_FL
)) &&
51 !capable( CAP_LINUX_IMMUTABLE
) )
54 if( ( flags
& REISERFS_NOTAIL_FL
) &&
55 S_ISREG( inode
-> i_mode
) ) {
58 result
= reiserfs_unpack( inode
, filp
);
62 sd_attrs_to_i_attrs( flags
, inode
);
63 REISERFS_I(inode
) -> i_attrs
= flags
;
64 inode
->i_ctime
= CURRENT_TIME
;
65 mark_inode_dirty(inode
);
68 case REISERFS_IOC_GETVERSION
:
69 return put_user(inode
->i_generation
, (int __user
*) arg
);
70 case REISERFS_IOC_SETVERSION
:
71 if ((current
->fsuid
!= inode
->i_uid
) && !capable(CAP_FOWNER
))
75 if (get_user(inode
->i_generation
, (int __user
*) arg
))
77 inode
->i_ctime
= CURRENT_TIME
;
78 mark_inode_dirty(inode
);
87 ** Function try to convert tail from direct item into indirect.
88 ** It set up nopack attribute in the REISERFS_I(inode)->nopack
90 int reiserfs_unpack (struct inode
* inode
, struct file
* filp
)
95 struct address_space
*mapping
;
96 unsigned long write_from
;
97 unsigned long blocksize
= inode
->i_sb
->s_blocksize
;
99 if (inode
->i_size
== 0) {
100 REISERFS_I(inode
)->i_flags
|= i_nopack_mask
;
103 /* ioctl already done */
104 if (REISERFS_I(inode
)->i_flags
& i_nopack_mask
) {
107 reiserfs_write_lock(inode
->i_sb
);
109 /* we need to make sure nobody is changing the file size beneath
112 down(&inode
->i_sem
) ;
114 write_from
= inode
->i_size
& (blocksize
- 1) ;
115 /* if we are on a block boundary, we are already unpacked. */
116 if ( write_from
== 0) {
117 REISERFS_I(inode
)->i_flags
|= i_nopack_mask
;
121 /* we unpack by finding the page with the tail, and calling
122 ** reiserfs_prepare_write on that page. This will force a
123 ** reiserfs_get_block to unpack the tail for us.
125 index
= inode
->i_size
>> PAGE_CACHE_SHIFT
;
126 mapping
= inode
->i_mapping
;
127 page
= grab_cache_page(mapping
, index
) ;
132 retval
= mapping
->a_ops
->prepare_write(NULL
, page
, write_from
, write_from
) ;
136 /* conversion can change page contents, must flush */
137 flush_dcache_page(page
) ;
138 retval
= mapping
->a_ops
->commit_write(NULL
, page
, write_from
, write_from
) ;
139 REISERFS_I(inode
)->i_flags
|= i_nopack_mask
;
143 page_cache_release(page
) ;
147 reiserfs_write_unlock(inode
->i_sb
);