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>
12 static int reiserfs_unpack (struct inode
* inode
, struct file
* filp
);
15 ** reiserfs_ioctl - handler for ioctl for inode
16 ** supported commands:
17 ** 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
18 ** and prevent packing file (argument arg has to be non-zero)
19 ** 2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
20 ** 3) That's all for a while ...
22 int reiserfs_ioctl (struct inode
* inode
, struct file
* filp
, unsigned int cmd
,
28 case REISERFS_IOC_UNPACK
:
29 if( S_ISREG( inode
-> i_mode
) ) {
31 return reiserfs_unpack (inode
, filp
);
36 /* following two cases are taken from fs/ext2/ioctl.c by Remy
37 Card (card@masi.ibp.fr) */
38 case REISERFS_IOC_GETFLAGS
:
39 flags
= REISERFS_I(inode
) -> i_attrs
;
40 i_attrs_to_sd_attrs( inode
, ( __u16
* ) &flags
);
41 return put_user(flags
, (int __user
*) arg
);
42 case REISERFS_IOC_SETFLAGS
: {
46 if ((current
->fsuid
!= inode
->i_uid
) && !capable(CAP_FOWNER
))
49 if (get_user(flags
, (int __user
*) arg
))
52 if ( ( ( flags
^ REISERFS_I(inode
) -> i_attrs
) & ( REISERFS_IMMUTABLE_FL
| REISERFS_APPEND_FL
)) &&
53 !capable( CAP_LINUX_IMMUTABLE
) )
56 if( ( flags
& REISERFS_NOTAIL_FL
) &&
57 S_ISREG( inode
-> i_mode
) ) {
60 result
= reiserfs_unpack( inode
, filp
);
64 sd_attrs_to_i_attrs( flags
, inode
);
65 REISERFS_I(inode
) -> i_attrs
= flags
;
66 inode
->i_ctime
= CURRENT_TIME_SEC
;
67 mark_inode_dirty(inode
);
70 case REISERFS_IOC_GETVERSION
:
71 return put_user(inode
->i_generation
, (int __user
*) arg
);
72 case REISERFS_IOC_SETVERSION
:
73 if ((current
->fsuid
!= inode
->i_uid
) && !capable(CAP_FOWNER
))
77 if (get_user(inode
->i_generation
, (int __user
*) arg
))
79 inode
->i_ctime
= CURRENT_TIME_SEC
;
80 mark_inode_dirty(inode
);
89 ** Function try to convert tail from direct item into indirect.
90 ** It set up nopack attribute in the REISERFS_I(inode)->nopack
92 static int reiserfs_unpack (struct inode
* inode
, struct file
* filp
)
97 struct address_space
*mapping
;
98 unsigned long write_from
;
99 unsigned long blocksize
= inode
->i_sb
->s_blocksize
;
101 if (inode
->i_size
== 0) {
102 REISERFS_I(inode
)->i_flags
|= i_nopack_mask
;
105 /* ioctl already done */
106 if (REISERFS_I(inode
)->i_flags
& i_nopack_mask
) {
109 reiserfs_write_lock(inode
->i_sb
);
111 /* we need to make sure nobody is changing the file size beneath
114 down(&inode
->i_sem
) ;
116 write_from
= inode
->i_size
& (blocksize
- 1) ;
117 /* if we are on a block boundary, we are already unpacked. */
118 if ( write_from
== 0) {
119 REISERFS_I(inode
)->i_flags
|= i_nopack_mask
;
123 /* we unpack by finding the page with the tail, and calling
124 ** reiserfs_prepare_write on that page. This will force a
125 ** reiserfs_get_block to unpack the tail for us.
127 index
= inode
->i_size
>> PAGE_CACHE_SHIFT
;
128 mapping
= inode
->i_mapping
;
129 page
= grab_cache_page(mapping
, index
) ;
134 retval
= mapping
->a_ops
->prepare_write(NULL
, page
, write_from
, write_from
) ;
138 /* conversion can change page contents, must flush */
139 flush_dcache_page(page
) ;
140 retval
= mapping
->a_ops
->commit_write(NULL
, page
, write_from
, write_from
) ;
141 REISERFS_I(inode
)->i_flags
|= i_nopack_mask
;
145 page_cache_release(page
) ;
149 reiserfs_write_unlock(inode
->i_sb
);