Blame view
fs/reiserfs/ioctl.c
5.28 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 |
/* * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README */ |
16f7e0fe2 [PATCH] capable/c... |
4 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
5 |
#include <linux/fs.h> |
42a74f206 [PATCH] r/o bind ... |
6 |
#include <linux/mount.h> |
f466c6fdb move private bits... |
7 |
#include "reiserfs.h" |
1da177e4c Linux-2.6.12-rc2 |
8 |
#include <linux/time.h> |
17093991a fs/reiserfs: use ... |
9 |
#include <linux/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
10 |
#include <linux/pagemap.h> |
52b499c43 [PATCH] BLOCK: Mo... |
11 |
#include <linux/compat.h> |
1da177e4c Linux-2.6.12-rc2 |
12 |
|
1da177e4c Linux-2.6.12-rc2 |
13 |
/* |
ac78a0789 kill-the-bkl/reis... |
14 15 16 |
* reiserfs_ioctl - handler for ioctl for inode * supported commands: * 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect |
098297b27 reiserfs: cleanup... |
17 18 |
* and prevent packing file (argument arg has t * be non-zero) |
ac78a0789 kill-the-bkl/reis... |
19 20 21 |
* 2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION * 3) That's all for a while ... */ |
205cb37b8 kill-the-bkl/reis... |
22 |
long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
1da177e4c Linux-2.6.12-rc2 |
23 |
{ |
496ad9aa8 new helper: file_... |
24 |
struct inode *inode = file_inode(filp); |
1da177e4c Linux-2.6.12-rc2 |
25 |
unsigned int flags; |
42a74f206 [PATCH] r/o bind ... |
26 |
int err = 0; |
1da177e4c Linux-2.6.12-rc2 |
27 |
|
ac78a0789 kill-the-bkl/reis... |
28 |
reiserfs_write_lock(inode->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
29 |
switch (cmd) { |
bd4c625c0 reiserfs: run scr... |
30 31 32 |
case REISERFS_IOC_UNPACK: if (S_ISREG(inode->i_mode)) { if (arg) |
ac78a0789 kill-the-bkl/reis... |
33 |
err = reiserfs_unpack(inode, filp); |
1da177e4c Linux-2.6.12-rc2 |
34 |
} else |
ac78a0789 kill-the-bkl/reis... |
35 36 37 38 39 40 |
err = -ENOTTY; break; /* * following two cases are taken from fs/ext2/ioctl.c by Remy * Card (card@masi.ibp.fr) */ |
1da177e4c Linux-2.6.12-rc2 |
41 |
case REISERFS_IOC_GETFLAGS: |
ac78a0789 kill-the-bkl/reis... |
42 43 44 45 |
if (!reiserfs_attrs(inode->i_sb)) { err = -ENOTTY; break; } |
869eb76e7 [PATCH] reiserfs:... |
46 |
|
bd4c625c0 reiserfs: run scr... |
47 |
flags = REISERFS_I(inode)->i_attrs; |
ac78a0789 kill-the-bkl/reis... |
48 49 |
err = put_user(flags, (int __user *)arg); break; |
bd4c625c0 reiserfs: run scr... |
50 |
case REISERFS_IOC_SETFLAGS:{ |
ac78a0789 kill-the-bkl/reis... |
51 52 53 54 |
if (!reiserfs_attrs(inode->i_sb)) { err = -ENOTTY; break; } |
869eb76e7 [PATCH] reiserfs:... |
55 |
|
a561be710 switch a bunch of... |
56 |
err = mnt_want_write_file(filp); |
42a74f206 [PATCH] r/o bind ... |
57 |
if (err) |
ac78a0789 kill-the-bkl/reis... |
58 |
break; |
1da177e4c Linux-2.6.12-rc2 |
59 |
|
2e1496707 userns: rename is... |
60 |
if (!inode_owner_or_capable(inode)) { |
42a74f206 [PATCH] r/o bind ... |
61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
err = -EPERM; goto setflags_out; } if (get_user(flags, (int __user *)arg)) { err = -EFAULT; goto setflags_out; } /* * Is it quota file? Do not allow user to mess with it */ if (IS_NOQUOTA(inode)) { err = -EPERM; goto setflags_out; } |
5aca28421 vfs: create a gen... |
75 76 77 78 |
err = vfs_ioc_setflags_prepare(inode, REISERFS_I(inode)->i_attrs, flags); if (err) |
42a74f206 [PATCH] r/o bind ... |
79 |
goto setflags_out; |
bd4c625c0 reiserfs: run scr... |
80 81 |
if ((flags & REISERFS_NOTAIL_FL) && S_ISREG(inode->i_mode)) { |
1da177e4c Linux-2.6.12-rc2 |
82 |
int result; |
bd4c625c0 reiserfs: run scr... |
83 |
result = reiserfs_unpack(inode, filp); |
42a74f206 [PATCH] r/o bind ... |
84 85 86 87 |
if (result) { err = result; goto setflags_out; } |
bd4c625c0 reiserfs: run scr... |
88 89 90 |
} sd_attrs_to_i_attrs(flags, inode); REISERFS_I(inode)->i_attrs = flags; |
02027d42c fs: Replace CURRE... |
91 |
inode->i_ctime = current_time(inode); |
bd4c625c0 reiserfs: run scr... |
92 |
mark_inode_dirty(inode); |
42a74f206 [PATCH] r/o bind ... |
93 |
setflags_out: |
2a79f17e4 vfs: mnt_drop_wri... |
94 |
mnt_drop_write_file(filp); |
ac78a0789 kill-the-bkl/reis... |
95 |
break; |
1da177e4c Linux-2.6.12-rc2 |
96 |
} |
1da177e4c Linux-2.6.12-rc2 |
97 |
case REISERFS_IOC_GETVERSION: |
ac78a0789 kill-the-bkl/reis... |
98 99 |
err = put_user(inode->i_generation, (int __user *)arg); break; |
1da177e4c Linux-2.6.12-rc2 |
100 |
case REISERFS_IOC_SETVERSION: |
2e1496707 userns: rename is... |
101 |
if (!inode_owner_or_capable(inode)) { |
ac78a0789 kill-the-bkl/reis... |
102 103 |
err = -EPERM; break; |
e0baec1b6 reiserfs: Fix unr... |
104 |
} |
a561be710 switch a bunch of... |
105 |
err = mnt_want_write_file(filp); |
42a74f206 [PATCH] r/o bind ... |
106 |
if (err) |
ac78a0789 kill-the-bkl/reis... |
107 |
break; |
42a74f206 [PATCH] r/o bind ... |
108 109 110 111 |
if (get_user(inode->i_generation, (int __user *)arg)) { err = -EFAULT; goto setversion_out; } |
02027d42c fs: Replace CURRE... |
112 |
inode->i_ctime = current_time(inode); |
1da177e4c Linux-2.6.12-rc2 |
113 |
mark_inode_dirty(inode); |
42a74f206 [PATCH] r/o bind ... |
114 |
setversion_out: |
2a79f17e4 vfs: mnt_drop_wri... |
115 |
mnt_drop_write_file(filp); |
ac78a0789 kill-the-bkl/reis... |
116 |
break; |
1da177e4c Linux-2.6.12-rc2 |
117 |
default: |
ac78a0789 kill-the-bkl/reis... |
118 |
err = -ENOTTY; |
1da177e4c Linux-2.6.12-rc2 |
119 |
} |
ac78a0789 kill-the-bkl/reis... |
120 121 122 123 |
reiserfs_write_unlock(inode->i_sb); return err; |
1da177e4c Linux-2.6.12-rc2 |
124 |
} |
52b499c43 [PATCH] BLOCK: Mo... |
125 126 127 128 |
#ifdef CONFIG_COMPAT long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { |
098297b27 reiserfs: cleanup... |
129 130 131 132 |
/* * These are just misnamed, they actually * get/put from/to user an int */ |
52b499c43 [PATCH] BLOCK: Mo... |
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
switch (cmd) { case REISERFS_IOC32_UNPACK: cmd = REISERFS_IOC_UNPACK; break; case REISERFS_IOC32_GETFLAGS: cmd = REISERFS_IOC_GETFLAGS; break; case REISERFS_IOC32_SETFLAGS: cmd = REISERFS_IOC_SETFLAGS; break; case REISERFS_IOC32_GETVERSION: cmd = REISERFS_IOC_GETVERSION; break; case REISERFS_IOC32_SETVERSION: cmd = REISERFS_IOC_SETVERSION; break; default: return -ENOIOCTLCMD; } |
8ebc42323 reiserfs: kill-th... |
152 |
|
205cb37b8 kill-the-bkl/reis... |
153 |
return reiserfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); |
52b499c43 [PATCH] BLOCK: Mo... |
154 155 |
} #endif |
ba9d8cec6 reiserfs: convert... |
156 157 |
int reiserfs_commit_write(struct file *f, struct page *page, unsigned from, unsigned to); |
1da177e4c Linux-2.6.12-rc2 |
158 |
/* |
098297b27 reiserfs: cleanup... |
159 160 161 162 |
* reiserfs_unpack * Function try to convert tail from direct item into indirect. * It set up nopack attribute in the REISERFS_I(inode)->nopack */ |
d5dee5c39 reiserfs: unpack ... |
163 |
int reiserfs_unpack(struct inode *inode, struct file *filp) |
1da177e4c Linux-2.6.12-rc2 |
164 |
{ |
bd4c625c0 reiserfs: run scr... |
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
int retval = 0; int index; struct page *page; struct address_space *mapping; unsigned long write_from; unsigned long blocksize = inode->i_sb->s_blocksize; if (inode->i_size == 0) { REISERFS_I(inode)->i_flags |= i_nopack_mask; return 0; } /* ioctl already done */ if (REISERFS_I(inode)->i_flags & i_nopack_mask) { return 0; } |
bd4c625c0 reiserfs: run scr... |
180 |
|
da905873e reiserfs: fix ino... |
181 |
/* we need to make sure nobody is changing the file size beneath us */ |
1ae1f3f64 reiserfs: open-co... |
182 183 184 185 186 |
{ int depth = reiserfs_write_unlock_nested(inode->i_sb); inode_lock(inode); reiserfs_write_lock_nested(inode->i_sb, depth); } |
da905873e reiserfs: fix ino... |
187 |
|
278f6679f reiserfs: locking... |
188 |
reiserfs_write_lock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
189 190 191 192 193 194 |
write_from = inode->i_size & (blocksize - 1); /* if we are on a block boundary, we are already unpacked. */ if (write_from == 0) { REISERFS_I(inode)->i_flags |= i_nopack_mask; goto out; } |
098297b27 reiserfs: cleanup... |
195 196 197 198 |
/* * we unpack by finding the page with the tail, and calling * __reiserfs_write_begin on that page. This will force a * reiserfs_get_block to unpack the tail for us. |
bd4c625c0 reiserfs: run scr... |
199 |
*/ |
09cbfeaf1 mm, fs: get rid o... |
200 |
index = inode->i_size >> PAGE_SHIFT; |
bd4c625c0 reiserfs: run scr... |
201 202 203 204 205 206 |
mapping = inode->i_mapping; page = grab_cache_page(mapping, index); retval = -ENOMEM; if (!page) { goto out; } |
ebdec241d fs: kill block_pr... |
207 |
retval = __reiserfs_write_begin(page, write_from, 0); |
bd4c625c0 reiserfs: run scr... |
208 209 210 211 212 |
if (retval) goto out_unlock; /* conversion can change page contents, must flush */ flush_dcache_page(page); |
ba9d8cec6 reiserfs: convert... |
213 |
retval = reiserfs_commit_write(NULL, page, write_from, write_from); |
1da177e4c Linux-2.6.12-rc2 |
214 |
REISERFS_I(inode)->i_flags |= i_nopack_mask; |
bd4c625c0 reiserfs: run scr... |
215 |
|
cf776a7a4 reiserfs: cleanup... |
216 |
out_unlock: |
bd4c625c0 reiserfs: run scr... |
217 |
unlock_page(page); |
09cbfeaf1 mm, fs: get rid o... |
218 |
put_page(page); |
bd4c625c0 reiserfs: run scr... |
219 |
|
cf776a7a4 reiserfs: cleanup... |
220 |
out: |
5955102c9 wrappers for ->i_... |
221 |
inode_unlock(inode); |
278f6679f reiserfs: locking... |
222 |
reiserfs_write_unlock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
223 |
return retval; |
1da177e4c Linux-2.6.12-rc2 |
224 |
} |