Blame view
fs/xfs/xfs_ioctl.c
34.6 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
7b7187698 [XFS] Update lice... |
2 3 |
* Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. |
1da177e4c Linux-2.6.12-rc2 |
4 |
* |
7b7187698 [XFS] Update lice... |
5 6 |
* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as |
1da177e4c Linux-2.6.12-rc2 |
7 8 |
* published by the Free Software Foundation. * |
7b7187698 [XFS] Update lice... |
9 10 11 12 |
* This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. |
1da177e4c Linux-2.6.12-rc2 |
13 |
* |
7b7187698 [XFS] Update lice... |
14 15 16 |
* You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1da177e4c Linux-2.6.12-rc2 |
17 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
18 |
#include "xfs.h" |
1da177e4c Linux-2.6.12-rc2 |
19 |
#include "xfs_fs.h" |
a844f4510 [XFS] Remove xfs_... |
20 |
#include "xfs_bit.h" |
1da177e4c Linux-2.6.12-rc2 |
21 |
#include "xfs_log.h" |
a844f4510 [XFS] Remove xfs_... |
22 |
#include "xfs_inum.h" |
1da177e4c Linux-2.6.12-rc2 |
23 24 |
#include "xfs_trans.h" #include "xfs_sb.h" |
a844f4510 [XFS] Remove xfs_... |
25 |
#include "xfs_ag.h" |
1da177e4c Linux-2.6.12-rc2 |
26 |
#include "xfs_alloc.h" |
1da177e4c Linux-2.6.12-rc2 |
27 |
#include "xfs_mount.h" |
1da177e4c Linux-2.6.12-rc2 |
28 |
#include "xfs_bmap_btree.h" |
1da177e4c Linux-2.6.12-rc2 |
29 30 |
#include "xfs_dinode.h" #include "xfs_inode.h" |
7bf446f8b xfs: include head... |
31 |
#include "xfs_ioctl.h" |
1da177e4c Linux-2.6.12-rc2 |
32 |
#include "xfs_rtalloc.h" |
1da177e4c Linux-2.6.12-rc2 |
33 |
#include "xfs_itable.h" |
a844f4510 [XFS] Remove xfs_... |
34 |
#include "xfs_error.h" |
1da177e4c Linux-2.6.12-rc2 |
35 |
#include "xfs_attr.h" |
a844f4510 [XFS] Remove xfs_... |
36 |
#include "xfs_bmap.h" |
1da177e4c Linux-2.6.12-rc2 |
37 38 39 40 |
#include "xfs_buf_item.h" #include "xfs_utils.h" #include "xfs_dfrag.h" #include "xfs_fsops.h" |
993386c19 [XFS] decontamina... |
41 |
#include "xfs_vnodeops.h" |
a46db6083 xfs: add FITRIM s... |
42 |
#include "xfs_discard.h" |
25fe55e81 [XFS] xfs_setattr... |
43 44 |
#include "xfs_quota.h" #include "xfs_inode_item.h" |
d296d30a9 xfs: fix dentry a... |
45 |
#include "xfs_export.h" |
0b1b213fc xfs: event tracin... |
46 |
#include "xfs_trace.h" |
1da177e4c Linux-2.6.12-rc2 |
47 |
|
16f7e0fe2 [PATCH] capable/c... |
48 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
49 50 51 52 |
#include <linux/dcache.h> #include <linux/mount.h> #include <linux/namei.h> #include <linux/pagemap.h> |
5a0e3ad6a include cleanup: ... |
53 |
#include <linux/slab.h> |
d296d30a9 xfs: fix dentry a... |
54 |
#include <linux/exportfs.h> |
1da177e4c Linux-2.6.12-rc2 |
55 56 57 58 59 60 61 62 63 64 65 66 |
/* * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to * a file or fs handle. * * XFS_IOC_PATH_TO_FSHANDLE * returns fs handle for a mount point or path within that mount point * XFS_IOC_FD_TO_HANDLE * returns full handle for a FD opened in user space * XFS_IOC_PATH_TO_HANDLE * returns full handle for a path */ |
d5547f9fe [XFS] Clean up so... |
67 |
int |
1da177e4c Linux-2.6.12-rc2 |
68 69 |
xfs_find_handle( unsigned int cmd, |
743bb4650 [XFS] Move copy_f... |
70 |
xfs_fsop_handlereq_t *hreq) |
1da177e4c Linux-2.6.12-rc2 |
71 72 73 |
{ int hsize; xfs_handle_t handle; |
1da177e4c Linux-2.6.12-rc2 |
74 |
struct inode *inode; |
4346cdd46 xfs: cleanup xfs_... |
75 76 77 78 |
struct file *file = NULL; struct path path; int error; struct xfs_inode *ip; |
1da177e4c Linux-2.6.12-rc2 |
79 |
|
4346cdd46 xfs: cleanup xfs_... |
80 |
if (cmd == XFS_IOC_FD_TO_HANDLE) { |
743bb4650 [XFS] Move copy_f... |
81 |
file = fget(hreq->fd); |
1da177e4c Linux-2.6.12-rc2 |
82 |
if (!file) |
4346cdd46 xfs: cleanup xfs_... |
83 84 85 86 87 88 89 |
return -EBADF; inode = file->f_path.dentry->d_inode; } else { error = user_lpath((const char __user *)hreq->path, &path); if (error) return error; inode = path.dentry->d_inode; |
1da177e4c Linux-2.6.12-rc2 |
90 |
} |
4346cdd46 xfs: cleanup xfs_... |
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
ip = XFS_I(inode); /* * We can only generate handles for inodes residing on a XFS filesystem, * and only for regular files, directories or symbolic links. */ error = -EINVAL; if (inode->i_sb->s_magic != XFS_SB_MAGIC) goto out_put; error = -EBADF; if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) && !S_ISLNK(inode->i_mode)) goto out_put; memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t)); if (cmd == XFS_IOC_PATH_TO_FSHANDLE) { /* * This handle only contains an fsid, zero the rest. */ memset(&handle.ha_fid, 0, sizeof(handle.ha_fid)); hsize = sizeof(xfs_fsid_t); } else { |
1da177e4c Linux-2.6.12-rc2 |
117 |
int lock_mode; |
1da177e4c Linux-2.6.12-rc2 |
118 |
lock_mode = xfs_ilock_map_shared(ip); |
c6143911a [XFS] cleanup fid... |
119 120 121 122 123 |
handle.ha_fid.fid_len = sizeof(xfs_fid_t) - sizeof(handle.ha_fid.fid_len); handle.ha_fid.fid_pad = 0; handle.ha_fid.fid_gen = ip->i_d.di_gen; handle.ha_fid.fid_ino = ip->i_ino; |
1da177e4c Linux-2.6.12-rc2 |
124 125 126 127 |
xfs_iunlock_map_shared(ip, lock_mode); hsize = XFS_HSIZE(handle); } |
4346cdd46 xfs: cleanup xfs_... |
128 |
error = -EFAULT; |
743bb4650 [XFS] Move copy_f... |
129 |
if (copy_to_user(hreq->ohandle, &handle, hsize) || |
4346cdd46 xfs: cleanup xfs_... |
130 131 |
copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) goto out_put; |
1da177e4c Linux-2.6.12-rc2 |
132 |
|
4346cdd46 xfs: cleanup xfs_... |
133 134 135 136 137 138 139 140 |
error = 0; out_put: if (cmd == XFS_IOC_FD_TO_HANDLE) fput(file); else path_put(&path); return error; |
1da177e4c Linux-2.6.12-rc2 |
141 |
} |
1da177e4c Linux-2.6.12-rc2 |
142 |
/* |
d296d30a9 xfs: fix dentry a... |
143 144 |
* No need to do permission checks on the various pathname components * as the handle operations are privileged. |
1da177e4c Linux-2.6.12-rc2 |
145 146 |
*/ STATIC int |
d296d30a9 xfs: fix dentry a... |
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
xfs_handle_acceptable( void *context, struct dentry *dentry) { return 1; } /* * Convert userspace handle data into a dentry. */ struct dentry * xfs_handle_to_dentry( struct file *parfilp, void __user *uhandle, u32 hlen) |
1da177e4c Linux-2.6.12-rc2 |
162 |
{ |
1da177e4c Linux-2.6.12-rc2 |
163 |
xfs_handle_t handle; |
d296d30a9 xfs: fix dentry a... |
164 |
struct xfs_fid64 fid; |
1da177e4c Linux-2.6.12-rc2 |
165 166 167 168 |
/* * Only allow handle opens under a directory. */ |
d296d30a9 xfs: fix dentry a... |
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
if (!S_ISDIR(parfilp->f_path.dentry->d_inode->i_mode)) return ERR_PTR(-ENOTDIR); if (hlen != sizeof(xfs_handle_t)) return ERR_PTR(-EINVAL); if (copy_from_user(&handle, uhandle, hlen)) return ERR_PTR(-EFAULT); if (handle.ha_fid.fid_len != sizeof(handle.ha_fid) - sizeof(handle.ha_fid.fid_len)) return ERR_PTR(-EINVAL); memset(&fid, 0, sizeof(struct fid)); fid.ino = handle.ha_fid.fid_ino; fid.gen = handle.ha_fid.fid_gen; return exportfs_decode_fh(parfilp->f_path.mnt, (struct fid *)&fid, 3, FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG, xfs_handle_acceptable, NULL); } |
1da177e4c Linux-2.6.12-rc2 |
188 |
|
d296d30a9 xfs: fix dentry a... |
189 190 191 192 193 194 |
STATIC struct dentry * xfs_handlereq_to_dentry( struct file *parfilp, xfs_fsop_handlereq_t *hreq) { return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen); |
1da177e4c Linux-2.6.12-rc2 |
195 |
} |
d5547f9fe [XFS] Clean up so... |
196 |
int |
1da177e4c Linux-2.6.12-rc2 |
197 |
xfs_open_by_handle( |
1da177e4c Linux-2.6.12-rc2 |
198 |
struct file *parfilp, |
d296d30a9 xfs: fix dentry a... |
199 |
xfs_fsop_handlereq_t *hreq) |
1da177e4c Linux-2.6.12-rc2 |
200 |
{ |
745ca2475 CRED: Pass creden... |
201 |
const struct cred *cred = current_cred(); |
1da177e4c Linux-2.6.12-rc2 |
202 |
int error; |
d296d30a9 xfs: fix dentry a... |
203 |
int fd; |
1da177e4c Linux-2.6.12-rc2 |
204 205 206 207 |
int permflag; struct file *filp; struct inode *inode; struct dentry *dentry; |
1da177e4c Linux-2.6.12-rc2 |
208 209 210 |
if (!capable(CAP_SYS_ADMIN)) return -XFS_ERROR(EPERM); |
1da177e4c Linux-2.6.12-rc2 |
211 |
|
d296d30a9 xfs: fix dentry a... |
212 213 214 215 |
dentry = xfs_handlereq_to_dentry(parfilp, hreq); if (IS_ERR(dentry)) return PTR_ERR(dentry); inode = dentry->d_inode; |
1da177e4c Linux-2.6.12-rc2 |
216 217 218 |
/* Restrict xfs_open_by_handle to directories & regular files. */ if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) { |
d296d30a9 xfs: fix dentry a... |
219 220 |
error = -XFS_ERROR(EPERM); goto out_dput; |
1da177e4c Linux-2.6.12-rc2 |
221 222 223 |
} #if BITS_PER_LONG != 32 |
743bb4650 [XFS] Move copy_f... |
224 |
hreq->oflags |= O_LARGEFILE; |
1da177e4c Linux-2.6.12-rc2 |
225 |
#endif |
d296d30a9 xfs: fix dentry a... |
226 |
|
1da177e4c Linux-2.6.12-rc2 |
227 |
/* Put open permission in namei format. */ |
743bb4650 [XFS] Move copy_f... |
228 |
permflag = hreq->oflags; |
1da177e4c Linux-2.6.12-rc2 |
229 230 231 232 233 234 235 |
if ((permflag+1) & O_ACCMODE) permflag++; if (permflag & O_TRUNC) permflag |= 2; if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) && (permflag & FMODE_WRITE) && IS_APPEND(inode)) { |
d296d30a9 xfs: fix dentry a... |
236 237 |
error = -XFS_ERROR(EPERM); goto out_dput; |
1da177e4c Linux-2.6.12-rc2 |
238 239 240 |
} if ((permflag & FMODE_WRITE) && IS_IMMUTABLE(inode)) { |
d296d30a9 xfs: fix dentry a... |
241 242 |
error = -XFS_ERROR(EACCES); goto out_dput; |
1da177e4c Linux-2.6.12-rc2 |
243 244 245 |
} /* Can't write directories. */ |
d296d30a9 xfs: fix dentry a... |
246 247 248 |
if (S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) { error = -XFS_ERROR(EISDIR); goto out_dput; |
1da177e4c Linux-2.6.12-rc2 |
249 |
} |
d296d30a9 xfs: fix dentry a... |
250 251 252 253 |
fd = get_unused_fd(); if (fd < 0) { error = fd; goto out_dput; |
1da177e4c Linux-2.6.12-rc2 |
254 |
} |
d296d30a9 xfs: fix dentry a... |
255 256 |
filp = dentry_open(dentry, mntget(parfilp->f_path.mnt), hreq->oflags, cred); |
1da177e4c Linux-2.6.12-rc2 |
257 |
if (IS_ERR(filp)) { |
d296d30a9 xfs: fix dentry a... |
258 259 |
put_unused_fd(fd); return PTR_ERR(filp); |
1da177e4c Linux-2.6.12-rc2 |
260 |
} |
4d4be482a [XFS] add a FMODE... |
261 |
|
03209378b xfs: fix misspell... |
262 |
if (S_ISREG(inode->i_mode)) { |
2e2e7bb1f [XFS] 956664: dm_... |
263 |
filp->f_flags |= O_NOATIME; |
4d4be482a [XFS] add a FMODE... |
264 |
filp->f_mode |= FMODE_NOCMTIME; |
2e2e7bb1f [XFS] 956664: dm_... |
265 |
} |
1da177e4c Linux-2.6.12-rc2 |
266 |
|
d296d30a9 xfs: fix dentry a... |
267 268 269 270 271 272 |
fd_install(fd, filp); return fd; out_dput: dput(dentry); return error; |
1da177e4c Linux-2.6.12-rc2 |
273 |
} |
804c83c37 [XFS] stop using ... |
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
/* * This is a copy from fs/namei.c:vfs_readlink(), except for removing it's * unused first argument. */ STATIC int do_readlink( char __user *buffer, int buflen, const char *link) { int len; len = PTR_ERR(link); if (IS_ERR(link)) goto out; len = strlen(link); if (len > (unsigned) buflen) len = buflen; if (copy_to_user(buffer, link, len)) len = -EFAULT; out: return len; } |
d5547f9fe [XFS] Clean up so... |
298 |
int |
1da177e4c Linux-2.6.12-rc2 |
299 |
xfs_readlink_by_handle( |
d296d30a9 xfs: fix dentry a... |
300 301 |
struct file *parfilp, xfs_fsop_handlereq_t *hreq) |
1da177e4c Linux-2.6.12-rc2 |
302 |
{ |
d296d30a9 xfs: fix dentry a... |
303 |
struct dentry *dentry; |
1da177e4c Linux-2.6.12-rc2 |
304 |
__u32 olen; |
804c83c37 [XFS] stop using ... |
305 306 |
void *link; int error; |
1da177e4c Linux-2.6.12-rc2 |
307 308 309 |
if (!capable(CAP_SYS_ADMIN)) return -XFS_ERROR(EPERM); |
1da177e4c Linux-2.6.12-rc2 |
310 |
|
d296d30a9 xfs: fix dentry a... |
311 312 313 |
dentry = xfs_handlereq_to_dentry(parfilp, hreq); if (IS_ERR(dentry)) return PTR_ERR(dentry); |
1da177e4c Linux-2.6.12-rc2 |
314 315 |
/* Restrict this handle operation to symlinks only. */ |
d296d30a9 xfs: fix dentry a... |
316 |
if (!S_ISLNK(dentry->d_inode->i_mode)) { |
804c83c37 [XFS] stop using ... |
317 |
error = -XFS_ERROR(EINVAL); |
d296d30a9 xfs: fix dentry a... |
318 |
goto out_dput; |
1da177e4c Linux-2.6.12-rc2 |
319 |
} |
743bb4650 [XFS] Move copy_f... |
320 |
if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) { |
804c83c37 [XFS] stop using ... |
321 |
error = -XFS_ERROR(EFAULT); |
d296d30a9 xfs: fix dentry a... |
322 |
goto out_dput; |
1da177e4c Linux-2.6.12-rc2 |
323 |
} |
1da177e4c Linux-2.6.12-rc2 |
324 |
|
804c83c37 [XFS] stop using ... |
325 |
link = kmalloc(MAXPATHLEN+1, GFP_KERNEL); |
d296d30a9 xfs: fix dentry a... |
326 327 328 329 |
if (!link) { error = -XFS_ERROR(ENOMEM); goto out_dput; } |
1da177e4c Linux-2.6.12-rc2 |
330 |
|
d296d30a9 xfs: fix dentry a... |
331 |
error = -xfs_readlink(XFS_I(dentry->d_inode), link); |
67fcaa73a [XFS] Resolve a n... |
332 |
if (error) |
804c83c37 [XFS] stop using ... |
333 |
goto out_kfree; |
743bb4650 [XFS] Move copy_f... |
334 |
error = do_readlink(hreq->ohandle, olen, link); |
804c83c37 [XFS] stop using ... |
335 336 |
if (error) goto out_kfree; |
67fcaa73a [XFS] Resolve a n... |
337 |
|
804c83c37 [XFS] stop using ... |
338 339 |
out_kfree: kfree(link); |
d296d30a9 xfs: fix dentry a... |
340 341 |
out_dput: dput(dentry); |
804c83c37 [XFS] stop using ... |
342 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
343 344 345 346 |
} STATIC int xfs_fssetdm_by_handle( |
d296d30a9 xfs: fix dentry a... |
347 348 |
struct file *parfilp, void __user *arg) |
1da177e4c Linux-2.6.12-rc2 |
349 350 351 352 |
{ int error; struct fsdmidata fsd; xfs_fsop_setdm_handlereq_t dmhreq; |
d296d30a9 xfs: fix dentry a... |
353 |
struct dentry *dentry; |
1da177e4c Linux-2.6.12-rc2 |
354 355 356 357 358 |
if (!capable(CAP_MKNOD)) return -XFS_ERROR(EPERM); if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t))) return -XFS_ERROR(EFAULT); |
d296d30a9 xfs: fix dentry a... |
359 360 361 |
dentry = xfs_handlereq_to_dentry(parfilp, &dmhreq.hreq); if (IS_ERR(dentry)) return PTR_ERR(dentry); |
1da177e4c Linux-2.6.12-rc2 |
362 |
|
d296d30a9 xfs: fix dentry a... |
363 |
if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode)) { |
6e7f75eaf [XFS] cleanup vno... |
364 365 |
error = -XFS_ERROR(EPERM); goto out; |
1da177e4c Linux-2.6.12-rc2 |
366 367 368 |
} if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) { |
6e7f75eaf [XFS] cleanup vno... |
369 370 |
error = -XFS_ERROR(EFAULT); goto out; |
1da177e4c Linux-2.6.12-rc2 |
371 |
} |
d296d30a9 xfs: fix dentry a... |
372 |
error = -xfs_set_dmattrs(XFS_I(dentry->d_inode), fsd.fsd_dmevmask, |
6e7f75eaf [XFS] cleanup vno... |
373 |
fsd.fsd_dmstate); |
1da177e4c Linux-2.6.12-rc2 |
374 |
|
6e7f75eaf [XFS] cleanup vno... |
375 |
out: |
d296d30a9 xfs: fix dentry a... |
376 |
dput(dentry); |
6e7f75eaf [XFS] cleanup vno... |
377 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
378 379 380 381 |
} STATIC int xfs_attrlist_by_handle( |
d296d30a9 xfs: fix dentry a... |
382 383 |
struct file *parfilp, void __user *arg) |
1da177e4c Linux-2.6.12-rc2 |
384 |
{ |
d296d30a9 xfs: fix dentry a... |
385 |
int error = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
386 387 |
attrlist_cursor_kern_t *cursor; xfs_fsop_attrlist_handlereq_t al_hreq; |
d296d30a9 xfs: fix dentry a... |
388 |
struct dentry *dentry; |
1da177e4c Linux-2.6.12-rc2 |
389 390 391 392 393 394 395 396 |
char *kbuf; if (!capable(CAP_SYS_ADMIN)) return -XFS_ERROR(EPERM); if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t))) return -XFS_ERROR(EFAULT); if (al_hreq.buflen > XATTR_LIST_MAX) return -XFS_ERROR(EINVAL); |
90ad58a83 [XFS] Check for i... |
397 398 399 400 401 |
/* * Reject flags, only allow namespaces. */ if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE)) return -XFS_ERROR(EINVAL); |
d296d30a9 xfs: fix dentry a... |
402 403 404 |
dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq); if (IS_ERR(dentry)) return PTR_ERR(dentry); |
1da177e4c Linux-2.6.12-rc2 |
405 |
|
6762b938e xfs: xfs_ioctl: f... |
406 |
kbuf = kzalloc(al_hreq.buflen, GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
407 |
if (!kbuf) |
d296d30a9 xfs: fix dentry a... |
408 |
goto out_dput; |
1da177e4c Linux-2.6.12-rc2 |
409 410 |
cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; |
d296d30a9 xfs: fix dentry a... |
411 |
error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen, |
739bfb2a7 [XFS] call common... |
412 |
al_hreq.flags, cursor); |
1da177e4c Linux-2.6.12-rc2 |
413 414 415 416 417 418 419 420 |
if (error) goto out_kfree; if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen)) error = -EFAULT; out_kfree: kfree(kbuf); |
d296d30a9 xfs: fix dentry a... |
421 422 423 |
out_dput: dput(dentry); return error; |
1da177e4c Linux-2.6.12-rc2 |
424 |
} |
28750975a [XFS] Hook up com... |
425 |
int |
1da177e4c Linux-2.6.12-rc2 |
426 |
xfs_attrmulti_attr_get( |
739bfb2a7 [XFS] call common... |
427 |
struct inode *inode, |
a9273ca5c xfs: convert attr... |
428 429 |
unsigned char *name, unsigned char __user *ubuf, |
1da177e4c Linux-2.6.12-rc2 |
430 431 432 |
__uint32_t *len, __uint32_t flags) { |
a9273ca5c xfs: convert attr... |
433 |
unsigned char *kbuf; |
1da177e4c Linux-2.6.12-rc2 |
434 |
int error = EFAULT; |
e8b0ebaa1 [XFS] Cleanup xfs... |
435 |
|
1da177e4c Linux-2.6.12-rc2 |
436 437 438 439 440 |
if (*len > XATTR_SIZE_MAX) return EINVAL; kbuf = kmalloc(*len, GFP_KERNEL); if (!kbuf) return ENOMEM; |
e8b0ebaa1 [XFS] Cleanup xfs... |
441 |
error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags); |
1da177e4c Linux-2.6.12-rc2 |
442 443 444 445 446 447 448 449 450 451 |
if (error) goto out_kfree; if (copy_to_user(ubuf, kbuf, *len)) error = EFAULT; out_kfree: kfree(kbuf); return error; } |
28750975a [XFS] Hook up com... |
452 |
int |
1da177e4c Linux-2.6.12-rc2 |
453 |
xfs_attrmulti_attr_set( |
739bfb2a7 [XFS] call common... |
454 |
struct inode *inode, |
a9273ca5c xfs: convert attr... |
455 456 |
unsigned char *name, const unsigned char __user *ubuf, |
1da177e4c Linux-2.6.12-rc2 |
457 458 459 |
__uint32_t len, __uint32_t flags) { |
a9273ca5c xfs: convert attr... |
460 |
unsigned char *kbuf; |
1da177e4c Linux-2.6.12-rc2 |
461 |
int error = EFAULT; |
739bfb2a7 [XFS] call common... |
462 |
if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
1da177e4c Linux-2.6.12-rc2 |
463 464 465 |
return EPERM; if (len > XATTR_SIZE_MAX) return EINVAL; |
0e639bdee xfs: use memdup_u... |
466 467 468 |
kbuf = memdup_user(ubuf, len); if (IS_ERR(kbuf)) return PTR_ERR(kbuf); |
e8b0ebaa1 [XFS] Cleanup xfs... |
469 |
|
739bfb2a7 [XFS] call common... |
470 |
error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); |
1da177e4c Linux-2.6.12-rc2 |
471 |
|
1da177e4c Linux-2.6.12-rc2 |
472 473 |
return error; } |
28750975a [XFS] Hook up com... |
474 |
int |
1da177e4c Linux-2.6.12-rc2 |
475 |
xfs_attrmulti_attr_remove( |
739bfb2a7 [XFS] call common... |
476 |
struct inode *inode, |
a9273ca5c xfs: convert attr... |
477 |
unsigned char *name, |
1da177e4c Linux-2.6.12-rc2 |
478 479 |
__uint32_t flags) { |
739bfb2a7 [XFS] call common... |
480 |
if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
1da177e4c Linux-2.6.12-rc2 |
481 |
return EPERM; |
739bfb2a7 [XFS] call common... |
482 |
return xfs_attr_remove(XFS_I(inode), name, flags); |
1da177e4c Linux-2.6.12-rc2 |
483 484 485 486 |
} STATIC int xfs_attrmulti_by_handle( |
42a74f206 [PATCH] r/o bind ... |
487 |
struct file *parfilp, |
d296d30a9 xfs: fix dentry a... |
488 |
void __user *arg) |
1da177e4c Linux-2.6.12-rc2 |
489 490 491 492 |
{ int error; xfs_attr_multiop_t *ops; xfs_fsop_attrmulti_handlereq_t am_hreq; |
d296d30a9 xfs: fix dentry a... |
493 |
struct dentry *dentry; |
1da177e4c Linux-2.6.12-rc2 |
494 |
unsigned int i, size; |
a9273ca5c xfs: convert attr... |
495 |
unsigned char *attr_name; |
1da177e4c Linux-2.6.12-rc2 |
496 497 498 499 500 |
if (!capable(CAP_SYS_ADMIN)) return -XFS_ERROR(EPERM); if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t))) return -XFS_ERROR(EFAULT); |
fda168c24 xfs: Fix integer ... |
501 502 503 |
/* overflow check */ if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t)) return -E2BIG; |
d296d30a9 xfs: fix dentry a... |
504 505 506 |
dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq); if (IS_ERR(dentry)) return PTR_ERR(dentry); |
1da177e4c Linux-2.6.12-rc2 |
507 508 |
error = E2BIG; |
e182f57ac [XFS] attrmulti c... |
509 |
size = am_hreq.opcount * sizeof(xfs_attr_multiop_t); |
1da177e4c Linux-2.6.12-rc2 |
510 |
if (!size || size > 16 * PAGE_SIZE) |
d296d30a9 xfs: fix dentry a... |
511 |
goto out_dput; |
1da177e4c Linux-2.6.12-rc2 |
512 |
|
0e639bdee xfs: use memdup_u... |
513 514 515 |
ops = memdup_user(am_hreq.ops, size); if (IS_ERR(ops)) { error = PTR_ERR(ops); |
d296d30a9 xfs: fix dentry a... |
516 |
goto out_dput; |
0e639bdee xfs: use memdup_u... |
517 |
} |
1da177e4c Linux-2.6.12-rc2 |
518 519 520 521 |
attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL); if (!attr_name) goto out_kfree_ops; |
1da177e4c Linux-2.6.12-rc2 |
522 523 |
error = 0; for (i = 0; i < am_hreq.opcount; i++) { |
a9273ca5c xfs: convert attr... |
524 |
ops[i].am_error = strncpy_from_user((char *)attr_name, |
1da177e4c Linux-2.6.12-rc2 |
525 526 527 528 529 530 531 532 |
ops[i].am_attrname, MAXNAMELEN); if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN) error = -ERANGE; if (ops[i].am_error < 0) break; switch (ops[i].am_opcode) { case ATTR_OP_GET: |
d296d30a9 xfs: fix dentry a... |
533 534 535 536 |
ops[i].am_error = xfs_attrmulti_attr_get( dentry->d_inode, attr_name, ops[i].am_attrvalue, &ops[i].am_length, ops[i].am_flags); |
1da177e4c Linux-2.6.12-rc2 |
537 538 |
break; case ATTR_OP_SET: |
a561be710 switch a bunch of... |
539 |
ops[i].am_error = mnt_want_write_file(parfilp); |
42a74f206 [PATCH] r/o bind ... |
540 541 |
if (ops[i].am_error) break; |
d296d30a9 xfs: fix dentry a... |
542 543 544 545 |
ops[i].am_error = xfs_attrmulti_attr_set( dentry->d_inode, attr_name, ops[i].am_attrvalue, ops[i].am_length, ops[i].am_flags); |
2a79f17e4 vfs: mnt_drop_wri... |
546 |
mnt_drop_write_file(parfilp); |
1da177e4c Linux-2.6.12-rc2 |
547 548 |
break; case ATTR_OP_REMOVE: |
a561be710 switch a bunch of... |
549 |
ops[i].am_error = mnt_want_write_file(parfilp); |
42a74f206 [PATCH] r/o bind ... |
550 551 |
if (ops[i].am_error) break; |
d296d30a9 xfs: fix dentry a... |
552 553 554 |
ops[i].am_error = xfs_attrmulti_attr_remove( dentry->d_inode, attr_name, ops[i].am_flags); |
2a79f17e4 vfs: mnt_drop_wri... |
555 |
mnt_drop_write_file(parfilp); |
1da177e4c Linux-2.6.12-rc2 |
556 557 558 559 560 561 562 563 564 565 566 567 |
break; default: ops[i].am_error = EINVAL; } } if (copy_to_user(am_hreq.ops, ops, size)) error = XFS_ERROR(EFAULT); kfree(attr_name); out_kfree_ops: kfree(ops); |
d296d30a9 xfs: fix dentry a... |
568 569 |
out_dput: dput(dentry); |
1da177e4c Linux-2.6.12-rc2 |
570 571 |
return -error; } |
d5547f9fe [XFS] Clean up so... |
572 |
int |
1da177e4c Linux-2.6.12-rc2 |
573 |
xfs_ioc_space( |
993386c19 [XFS] decontamina... |
574 |
struct xfs_inode *ip, |
f37ea1496 [XFS] pass inode ... |
575 |
struct inode *inode, |
1da177e4c Linux-2.6.12-rc2 |
576 577 578 |
struct file *filp, int ioflags, unsigned int cmd, |
743bb4650 [XFS] Move copy_f... |
579 |
xfs_flock64_t *bf) |
1da177e4c Linux-2.6.12-rc2 |
580 |
{ |
1da177e4c Linux-2.6.12-rc2 |
581 582 |
int attr_flags = 0; int error; |
743bb4650 [XFS] Move copy_f... |
583 584 585 586 587 588 589 |
/* * Only allow the sys admin to reserve space unless * unwritten extents are enabled. */ if (!xfs_sb_version_hasextflgbit(&ip->i_mount->m_sb) && !capable(CAP_SYS_ADMIN)) return -XFS_ERROR(EPERM); |
f37ea1496 [XFS] pass inode ... |
590 |
if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) |
1da177e4c Linux-2.6.12-rc2 |
591 |
return -XFS_ERROR(EPERM); |
ad4a8ac4e [XFS] Fix check f... |
592 |
if (!(filp->f_mode & FMODE_WRITE)) |
1da177e4c Linux-2.6.12-rc2 |
593 |
return -XFS_ERROR(EBADF); |
f37ea1496 [XFS] pass inode ... |
594 |
if (!S_ISREG(inode->i_mode)) |
1da177e4c Linux-2.6.12-rc2 |
595 |
return -XFS_ERROR(EINVAL); |
1da177e4c Linux-2.6.12-rc2 |
596 |
if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) |
0f285c8a1 [XFS] Now that xf... |
597 |
attr_flags |= XFS_ATTR_NONBLOCK; |
828788974 xfs: preallocatio... |
598 599 600 |
if (filp->f_flags & O_DSYNC) attr_flags |= XFS_ATTR_SYNC; |
1da177e4c Linux-2.6.12-rc2 |
601 |
if (ioflags & IO_INVIS) |
0f285c8a1 [XFS] Now that xf... |
602 |
attr_flags |= XFS_ATTR_DMI; |
1da177e4c Linux-2.6.12-rc2 |
603 |
|
743bb4650 [XFS] Move copy_f... |
604 |
error = xfs_change_file_space(ip, cmd, bf, filp->f_pos, attr_flags); |
1da177e4c Linux-2.6.12-rc2 |
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 |
return -error; } STATIC int xfs_ioc_bulkstat( xfs_mount_t *mp, unsigned int cmd, void __user *arg) { xfs_fsop_bulkreq_t bulkreq; int count; /* # of records returned */ xfs_ino_t inlast; /* last inode number */ int done; int error; /* done = 1 if there are more stats to get and if bulkstat */ /* should be called again (unused here, but used in dmapi) */ if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (XFS_FORCED_SHUTDOWN(mp)) return -XFS_ERROR(EIO); if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t))) return -XFS_ERROR(EFAULT); if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64))) return -XFS_ERROR(EFAULT); if ((count = bulkreq.icount) <= 0) return -XFS_ERROR(EINVAL); |
cd57e594a [XFS] 971064 Vari... |
637 638 |
if (bulkreq.ubuffer == NULL) return -XFS_ERROR(EINVAL); |
1da177e4c Linux-2.6.12-rc2 |
639 640 |
if (cmd == XFS_IOC_FSINUMBERS) error = xfs_inumbers(mp, &inlast, &count, |
faa63e958 [XFS] Fix XFS_IOC... |
641 |
bulkreq.ubuffer, xfs_inumbers_fmt); |
1da177e4c Linux-2.6.12-rc2 |
642 643 644 |
else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) error = xfs_bulkstat_single(mp, &inlast, bulkreq.ubuffer, &done); |
cd57e594a [XFS] 971064 Vari... |
645 |
else /* XFS_IOC_FSBULKSTAT */ |
7dce11dba xfs: always use i... |
646 647 648 |
error = xfs_bulkstat(mp, &inlast, &count, xfs_bulkstat_one, sizeof(xfs_bstat_t), bulkreq.ubuffer, &done); |
1da177e4c Linux-2.6.12-rc2 |
649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 |
if (error) return -error; if (bulkreq.ocount != NULL) { if (copy_to_user(bulkreq.lastip, &inlast, sizeof(xfs_ino_t))) return -XFS_ERROR(EFAULT); if (copy_to_user(bulkreq.ocount, &count, sizeof(count))) return -XFS_ERROR(EFAULT); } return 0; } STATIC int xfs_ioc_fsgeometry_v1( xfs_mount_t *mp, void __user *arg) { |
eeb2036b8 xfs: zero proper ... |
670 |
xfs_fsop_geom_t fsgeo; |
1da177e4c Linux-2.6.12-rc2 |
671 |
int error; |
eeb2036b8 xfs: zero proper ... |
672 |
error = xfs_fs_geometry(mp, &fsgeo, 3); |
1da177e4c Linux-2.6.12-rc2 |
673 674 |
if (error) return -error; |
eeb2036b8 xfs: zero proper ... |
675 676 677 678 679 680 |
/* * Caller should have passed an argument of type * xfs_fsop_geom_v1_t. This is a proper subset of the * xfs_fsop_geom_t that xfs_fs_geometry() fills in. */ if (copy_to_user(arg, &fsgeo, sizeof(xfs_fsop_geom_v1_t))) |
1da177e4c Linux-2.6.12-rc2 |
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 |
return -XFS_ERROR(EFAULT); return 0; } STATIC int xfs_ioc_fsgeometry( xfs_mount_t *mp, void __user *arg) { xfs_fsop_geom_t fsgeo; int error; error = xfs_fs_geometry(mp, &fsgeo, 4); if (error) return -error; if (copy_to_user(arg, &fsgeo, sizeof(fsgeo))) return -XFS_ERROR(EFAULT); return 0; } /* * Linux extended inode flags interface. */ |
1da177e4c Linux-2.6.12-rc2 |
705 706 707 708 709 710 711 |
STATIC unsigned int xfs_merge_ioc_xflags( unsigned int flags, unsigned int start) { unsigned int xflags = start; |
39058a0e1 [XFS] Clean up us... |
712 |
if (flags & FS_IMMUTABLE_FL) |
1da177e4c Linux-2.6.12-rc2 |
713 714 715 |
xflags |= XFS_XFLAG_IMMUTABLE; else xflags &= ~XFS_XFLAG_IMMUTABLE; |
39058a0e1 [XFS] Clean up us... |
716 |
if (flags & FS_APPEND_FL) |
1da177e4c Linux-2.6.12-rc2 |
717 718 719 |
xflags |= XFS_XFLAG_APPEND; else xflags &= ~XFS_XFLAG_APPEND; |
39058a0e1 [XFS] Clean up us... |
720 |
if (flags & FS_SYNC_FL) |
1da177e4c Linux-2.6.12-rc2 |
721 722 723 |
xflags |= XFS_XFLAG_SYNC; else xflags &= ~XFS_XFLAG_SYNC; |
39058a0e1 [XFS] Clean up us... |
724 |
if (flags & FS_NOATIME_FL) |
1da177e4c Linux-2.6.12-rc2 |
725 726 727 |
xflags |= XFS_XFLAG_NOATIME; else xflags &= ~XFS_XFLAG_NOATIME; |
39058a0e1 [XFS] Clean up us... |
728 |
if (flags & FS_NODUMP_FL) |
1da177e4c Linux-2.6.12-rc2 |
729 730 731 732 733 734 735 736 737 738 739 740 741 742 |
xflags |= XFS_XFLAG_NODUMP; else xflags &= ~XFS_XFLAG_NODUMP; return xflags; } STATIC unsigned int xfs_di2lxflags( __uint16_t di_flags) { unsigned int flags = 0; if (di_flags & XFS_DIFLAG_IMMUTABLE) |
39058a0e1 [XFS] Clean up us... |
743 |
flags |= FS_IMMUTABLE_FL; |
1da177e4c Linux-2.6.12-rc2 |
744 |
if (di_flags & XFS_DIFLAG_APPEND) |
39058a0e1 [XFS] Clean up us... |
745 |
flags |= FS_APPEND_FL; |
1da177e4c Linux-2.6.12-rc2 |
746 |
if (di_flags & XFS_DIFLAG_SYNC) |
39058a0e1 [XFS] Clean up us... |
747 |
flags |= FS_SYNC_FL; |
1da177e4c Linux-2.6.12-rc2 |
748 |
if (di_flags & XFS_DIFLAG_NOATIME) |
39058a0e1 [XFS] Clean up us... |
749 |
flags |= FS_NOATIME_FL; |
1da177e4c Linux-2.6.12-rc2 |
750 |
if (di_flags & XFS_DIFLAG_NODUMP) |
39058a0e1 [XFS] Clean up us... |
751 |
flags |= FS_NODUMP_FL; |
1da177e4c Linux-2.6.12-rc2 |
752 753 754 755 |
return flags; } STATIC int |
c83bfab1f [XFS] avoid xfs_g... |
756 757 758 759 760 761 |
xfs_ioc_fsgetxattr( xfs_inode_t *ip, int attr, void __user *arg) { struct fsxattr fa; |
a122eb2fd xfs: prevent read... |
762 |
memset(&fa, 0, sizeof(struct fsxattr)); |
c83bfab1f [XFS] avoid xfs_g... |
763 764 765 |
xfs_ilock(ip, XFS_ILOCK_SHARED); fa.fsx_xflags = xfs_ip2xflags(ip); fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog; |
6743099ce xfs: Extend proje... |
766 |
fa.fsx_projid = xfs_get_projid(ip); |
c83bfab1f [XFS] avoid xfs_g... |
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 |
if (attr) { if (ip->i_afp) { if (ip->i_afp->if_flags & XFS_IFEXTENTS) fa.fsx_nextents = ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t); else fa.fsx_nextents = ip->i_d.di_anextents; } else fa.fsx_nextents = 0; } else { if (ip->i_df.if_flags & XFS_IFEXTENTS) fa.fsx_nextents = ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t); else fa.fsx_nextents = ip->i_d.di_nextents; } xfs_iunlock(ip, XFS_ILOCK_SHARED); if (copy_to_user(arg, &fa, sizeof(fa))) return -EFAULT; return 0; } |
25fe55e81 [XFS] xfs_setattr... |
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 |
STATIC void xfs_set_diflags( struct xfs_inode *ip, unsigned int xflags) { unsigned int di_flags; /* can't set PREALLOC this way, just preserve it */ di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC); if (xflags & XFS_XFLAG_IMMUTABLE) di_flags |= XFS_DIFLAG_IMMUTABLE; if (xflags & XFS_XFLAG_APPEND) di_flags |= XFS_DIFLAG_APPEND; if (xflags & XFS_XFLAG_SYNC) di_flags |= XFS_DIFLAG_SYNC; if (xflags & XFS_XFLAG_NOATIME) di_flags |= XFS_DIFLAG_NOATIME; if (xflags & XFS_XFLAG_NODUMP) di_flags |= XFS_DIFLAG_NODUMP; if (xflags & XFS_XFLAG_PROJINHERIT) di_flags |= XFS_DIFLAG_PROJINHERIT; if (xflags & XFS_XFLAG_NODEFRAG) di_flags |= XFS_DIFLAG_NODEFRAG; if (xflags & XFS_XFLAG_FILESTREAM) di_flags |= XFS_DIFLAG_FILESTREAM; |
abbede1b3 xfs: get rid of o... |
815 |
if (S_ISDIR(ip->i_d.di_mode)) { |
25fe55e81 [XFS] xfs_setattr... |
816 817 818 819 820 821 |
if (xflags & XFS_XFLAG_RTINHERIT) di_flags |= XFS_DIFLAG_RTINHERIT; if (xflags & XFS_XFLAG_NOSYMLINKS) di_flags |= XFS_DIFLAG_NOSYMLINKS; if (xflags & XFS_XFLAG_EXTSZINHERIT) di_flags |= XFS_DIFLAG_EXTSZINHERIT; |
abbede1b3 xfs: get rid of o... |
822 |
} else if (S_ISREG(ip->i_d.di_mode)) { |
25fe55e81 [XFS] xfs_setattr... |
823 824 825 826 827 828 829 830 |
if (xflags & XFS_XFLAG_REALTIME) di_flags |= XFS_DIFLAG_REALTIME; if (xflags & XFS_XFLAG_EXTSIZE) di_flags |= XFS_DIFLAG_EXTSIZE; } ip->i_d.di_flags = di_flags; } |
f13fae2d2 [XFS] Remove vn_r... |
831 832 833 834 |
STATIC void xfs_diflags_to_linux( struct xfs_inode *ip) { |
e4f752910 [XFS] Kill shouty... |
835 |
struct inode *inode = VFS_I(ip); |
f13fae2d2 [XFS] Remove vn_r... |
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 |
unsigned int xflags = xfs_ip2xflags(ip); if (xflags & XFS_XFLAG_IMMUTABLE) inode->i_flags |= S_IMMUTABLE; else inode->i_flags &= ~S_IMMUTABLE; if (xflags & XFS_XFLAG_APPEND) inode->i_flags |= S_APPEND; else inode->i_flags &= ~S_APPEND; if (xflags & XFS_XFLAG_SYNC) inode->i_flags |= S_SYNC; else inode->i_flags &= ~S_SYNC; if (xflags & XFS_XFLAG_NOATIME) inode->i_flags |= S_NOATIME; else inode->i_flags &= ~S_NOATIME; } |
25fe55e81 [XFS] xfs_setattr... |
855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 |
#define FSX_PROJID 1 #define FSX_EXTSIZE 2 #define FSX_XFLAGS 4 #define FSX_NONBLOCK 8 STATIC int xfs_ioctl_setattr( xfs_inode_t *ip, struct fsxattr *fa, int mask) { struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; unsigned int lock_flags = 0; |
7d095257e xfs: kill xfs_qmops |
870 871 |
struct xfs_dquot *udqp = NULL; struct xfs_dquot *gdqp = NULL; |
25fe55e81 [XFS] xfs_setattr... |
872 873 |
struct xfs_dquot *olddquot = NULL; int code; |
cca28fb83 xfs: split xfs_it... |
874 |
trace_xfs_ioctl_setattr(ip); |
25fe55e81 [XFS] xfs_setattr... |
875 876 877 878 879 880 881 |
if (mp->m_flags & XFS_MOUNT_RDONLY) return XFS_ERROR(EROFS); if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); /* |
6743099ce xfs: Extend proje... |
882 |
* Disallow 32bit project ids when projid32bit feature is not enabled. |
23963e54c xfs: Disallow 32b... |
883 |
*/ |
6743099ce xfs: Extend proje... |
884 885 |
if ((mask & FSX_PROJID) && (fa->fsx_projid > (__uint16_t)-1) && !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb)) |
23963e54c xfs: Disallow 32b... |
886 887 888 |
return XFS_ERROR(EINVAL); /* |
25fe55e81 [XFS] xfs_setattr... |
889 890 891 892 893 894 895 896 |
* If disk quotas is on, we make sure that the dquots do exist on disk, * before we start any other transactions. Trying to do this later * is messy. We don't care to take a readlock to look at the ids * in inode here, because we can't hold it across the trans_reserve. * If the IDs do change before we take the ilock, we're covered * because the i_*dquot fields will get updated anyway. */ if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) { |
7d095257e xfs: kill xfs_qmops |
897 |
code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid, |
25fe55e81 [XFS] xfs_setattr... |
898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 |
ip->i_d.di_gid, fa->fsx_projid, XFS_QMOPT_PQUOTA, &udqp, &gdqp); if (code) return code; } /* * For the other attributes, we acquire the inode lock and * first do an error checking pass. */ tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); code = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0); if (code) goto error_return; lock_flags = XFS_ILOCK_EXCL; xfs_ilock(ip, lock_flags); /* * CAP_FOWNER overrides the following restrictions: * * The user ID of the calling process must be equal * to the file owner ID, except in cases where the * CAP_FSETID capability is applicable. */ |
91b777125 CRED: Wrap task c... |
923 |
if (current_fsuid() != ip->i_d.di_uid && !capable(CAP_FOWNER)) { |
25fe55e81 [XFS] xfs_setattr... |
924 925 926 927 928 929 930 931 |
code = XFS_ERROR(EPERM); goto error_return; } /* * Do a quota reservation only if projid is actually going to change. */ if (mask & FSX_PROJID) { |
7d095257e xfs: kill xfs_qmops |
932 933 |
if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp) && |
6743099ce xfs: Extend proje... |
934 |
xfs_get_projid(ip) != fa->fsx_projid) { |
25fe55e81 [XFS] xfs_setattr... |
935 |
ASSERT(tp); |
7d095257e xfs: kill xfs_qmops |
936 |
code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp, |
25fe55e81 [XFS] xfs_setattr... |
937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 |
capable(CAP_FOWNER) ? XFS_QMOPT_FORCE_RES : 0); if (code) /* out of quota */ goto error_return; } } if (mask & FSX_EXTSIZE) { /* * Can't change extent size if any extents are allocated. */ if (ip->i_d.di_nextents && ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize)) { code = XFS_ERROR(EINVAL); /* EFBIG? */ goto error_return; } /* * Extent size must be a multiple of the appropriate block |
5315837da xfs: limit extsiz... |
957 958 959 960 961 962 |
* size, if set at all. It must also be smaller than the * maximum extent size supported by the filesystem. * * Also, for non-realtime files, limit the extent size hint to * half the size of the AGs in the filesystem so alignment * doesn't result in extents larger than an AG. |
25fe55e81 [XFS] xfs_setattr... |
963 964 |
*/ if (fa->fsx_extsize != 0) { |
5315837da xfs: limit extsiz... |
965 966 967 968 969 970 971 972 |
xfs_extlen_t size; xfs_fsblock_t extsize_fsb; extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize); if (extsize_fsb > MAXEXTLEN) { code = XFS_ERROR(EINVAL); goto error_return; } |
25fe55e81 [XFS] xfs_setattr... |
973 974 975 976 977 978 979 980 |
if (XFS_IS_REALTIME_INODE(ip) || ((mask & FSX_XFLAGS) && (fa->fsx_xflags & XFS_XFLAG_REALTIME))) { size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog; } else { size = mp->m_sb.sb_blocksize; |
5315837da xfs: limit extsiz... |
981 982 983 984 |
if (extsize_fsb > mp->m_sb.sb_agblocks / 2) { code = XFS_ERROR(EINVAL); goto error_return; } |
25fe55e81 [XFS] xfs_setattr... |
985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 |
} if (fa->fsx_extsize % size) { code = XFS_ERROR(EINVAL); goto error_return; } } } if (mask & FSX_XFLAGS) { /* * Can't change realtime flag if any extents are allocated. */ if ((ip->i_d.di_nextents || ip->i_delayed_blks) && (XFS_IS_REALTIME_INODE(ip)) != (fa->fsx_xflags & XFS_XFLAG_REALTIME)) { code = XFS_ERROR(EINVAL); /* EFBIG? */ goto error_return; } /* * If realtime flag is set then must have realtime data. */ if ((fa->fsx_xflags & XFS_XFLAG_REALTIME)) { if ((mp->m_sb.sb_rblocks == 0) || (mp->m_sb.sb_rextsize == 0) || (ip->i_d.di_extsize % mp->m_sb.sb_rextsize)) { code = XFS_ERROR(EINVAL); goto error_return; } } /* * Can't modify an immutable/append-only file unless * we have appropriate permission. */ if ((ip->i_d.di_flags & (XFS_DIFLAG_IMMUTABLE|XFS_DIFLAG_APPEND) || (fa->fsx_xflags & (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) && !capable(CAP_LINUX_IMMUTABLE)) { code = XFS_ERROR(EPERM); goto error_return; } } |
ddc3415ab xfs: simplify xfs... |
1031 |
xfs_trans_ijoin(tp, ip, 0); |
25fe55e81 [XFS] xfs_setattr... |
1032 1033 1034 |
/* * Change file ownership. Must be the owner or privileged. |
25fe55e81 [XFS] xfs_setattr... |
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 |
*/ if (mask & FSX_PROJID) { /* * CAP_FSETID overrides the following restrictions: * * The set-user-ID and set-group-ID bits of a file will be * cleared upon successful return from chown() */ if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) && !capable(CAP_FSETID)) ip->i_d.di_mode &= ~(S_ISUID|S_ISGID); /* * Change the ownerships and register quota modifications * in the transaction. */ |
6743099ce xfs: Extend proje... |
1051 |
if (xfs_get_projid(ip) != fa->fsx_projid) { |
7d095257e xfs: kill xfs_qmops |
1052 1053 |
if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) { olddquot = xfs_qm_vop_chown(tp, ip, |
25fe55e81 [XFS] xfs_setattr... |
1054 1055 |
&ip->i_gdquot, gdqp); } |
6743099ce xfs: Extend proje... |
1056 |
xfs_set_projid(ip, fa->fsx_projid); |
25fe55e81 [XFS] xfs_setattr... |
1057 1058 1059 1060 1061 1062 |
/* * We may have to rev the inode as well as * the superblock version number since projids didn't * exist before DINODE_VERSION_2 and SB_VERSION_NLINK. */ |
51ce16d51 [XFS] kill XFS_DI... |
1063 |
if (ip->i_d.di_version == 1) |
25fe55e81 [XFS] xfs_setattr... |
1064 1065 1066 1067 1068 1069 1070 |
xfs_bump_ino_vers2(tp, ip); } } if (mask & FSX_EXTSIZE) ip->i_d.di_extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog; |
f13fae2d2 [XFS] Remove vn_r... |
1071 |
if (mask & FSX_XFLAGS) { |
25fe55e81 [XFS] xfs_setattr... |
1072 |
xfs_set_diflags(ip, fa->fsx_xflags); |
f13fae2d2 [XFS] Remove vn_r... |
1073 1074 |
xfs_diflags_to_linux(ip); } |
25fe55e81 [XFS] xfs_setattr... |
1075 |
|
dcd79a142 xfs: don't use vf... |
1076 |
xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); |
25fe55e81 [XFS] xfs_setattr... |
1077 |
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
25fe55e81 [XFS] xfs_setattr... |
1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 |
XFS_STATS_INC(xs_ig_attrchg); /* * If this is a synchronous mount, make sure that the * transaction goes to disk before returning to the user. * This is slightly sub-optimal in that truncates require * two sync transactions instead of one for wsync filesystems. * One for the truncate and one for the timestamps since we * don't want to change the timestamps unless we're sure the * truncate worked. Truncates are less than 1% of the laddis * mix so this probably isn't worth the trouble to optimize. */ if (mp->m_flags & XFS_MOUNT_WSYNC) xfs_trans_set_sync(tp); code = xfs_trans_commit(tp, 0); xfs_iunlock(ip, lock_flags); /* * Release any dquot(s) the inode had kept before chown. */ |
7d095257e xfs: kill xfs_qmops |
1099 1100 1101 |
xfs_qm_dqrele(olddquot); xfs_qm_dqrele(udqp); xfs_qm_dqrele(gdqp); |
25fe55e81 [XFS] xfs_setattr... |
1102 |
|
288699fec xfs: drop dmapi h... |
1103 |
return code; |
25fe55e81 [XFS] xfs_setattr... |
1104 1105 |
error_return: |
7d095257e xfs: kill xfs_qmops |
1106 1107 |
xfs_qm_dqrele(udqp); xfs_qm_dqrele(gdqp); |
25fe55e81 [XFS] xfs_setattr... |
1108 1109 1110 1111 1112 |
xfs_trans_cancel(tp, 0); if (lock_flags) xfs_iunlock(ip, lock_flags); return code; } |
c83bfab1f [XFS] avoid xfs_g... |
1113 |
STATIC int |
df26cfe84 [XFS] split xfs_i... |
1114 |
xfs_ioc_fssetxattr( |
1da177e4c Linux-2.6.12-rc2 |
1115 1116 |
xfs_inode_t *ip, struct file *filp, |
1da177e4c Linux-2.6.12-rc2 |
1117 1118 1119 |
void __user *arg) { struct fsxattr fa; |
25fe55e81 [XFS] xfs_setattr... |
1120 |
unsigned int mask; |
df26cfe84 [XFS] split xfs_i... |
1121 1122 1123 |
if (copy_from_user(&fa, arg, sizeof(fa))) return -EFAULT; |
1da177e4c Linux-2.6.12-rc2 |
1124 |
|
25fe55e81 [XFS] xfs_setattr... |
1125 |
mask = FSX_XFLAGS | FSX_EXTSIZE | FSX_PROJID; |
df26cfe84 [XFS] split xfs_i... |
1126 |
if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) |
25fe55e81 [XFS] xfs_setattr... |
1127 |
mask |= FSX_NONBLOCK; |
1da177e4c Linux-2.6.12-rc2 |
1128 |
|
25fe55e81 [XFS] xfs_setattr... |
1129 |
return -xfs_ioctl_setattr(ip, &fa, mask); |
df26cfe84 [XFS] split xfs_i... |
1130 |
} |
1da177e4c Linux-2.6.12-rc2 |
1131 |
|
df26cfe84 [XFS] split xfs_i... |
1132 1133 1134 1135 1136 1137 |
STATIC int xfs_ioc_getxflags( xfs_inode_t *ip, void __user *arg) { unsigned int flags; |
1da177e4c Linux-2.6.12-rc2 |
1138 |
|
df26cfe84 [XFS] split xfs_i... |
1139 1140 1141 1142 1143 |
flags = xfs_di2lxflags(ip->i_d.di_flags); if (copy_to_user(arg, &flags, sizeof(flags))) return -EFAULT; return 0; } |
1da177e4c Linux-2.6.12-rc2 |
1144 |
|
df26cfe84 [XFS] split xfs_i... |
1145 1146 1147 1148 1149 1150 |
STATIC int xfs_ioc_setxflags( xfs_inode_t *ip, struct file *filp, void __user *arg) { |
25fe55e81 [XFS] xfs_setattr... |
1151 |
struct fsxattr fa; |
df26cfe84 [XFS] split xfs_i... |
1152 |
unsigned int flags; |
25fe55e81 [XFS] xfs_setattr... |
1153 |
unsigned int mask; |
1da177e4c Linux-2.6.12-rc2 |
1154 |
|
df26cfe84 [XFS] split xfs_i... |
1155 1156 |
if (copy_from_user(&flags, arg, sizeof(flags))) return -EFAULT; |
1da177e4c Linux-2.6.12-rc2 |
1157 |
|
df26cfe84 [XFS] split xfs_i... |
1158 1159 1160 1161 |
if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ FS_NOATIME_FL | FS_NODUMP_FL | \ FS_SYNC_FL)) return -EOPNOTSUPP; |
1da177e4c Linux-2.6.12-rc2 |
1162 |
|
25fe55e81 [XFS] xfs_setattr... |
1163 |
mask = FSX_XFLAGS; |
df26cfe84 [XFS] split xfs_i... |
1164 |
if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) |
25fe55e81 [XFS] xfs_setattr... |
1165 1166 |
mask |= FSX_NONBLOCK; fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip)); |
1da177e4c Linux-2.6.12-rc2 |
1167 |
|
25fe55e81 [XFS] xfs_setattr... |
1168 |
return -xfs_ioctl_setattr(ip, &fa, mask); |
1da177e4c Linux-2.6.12-rc2 |
1169 1170 1171 |
} STATIC int |
8a7141a8b [XFS] convert xfs... |
1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 |
xfs_getbmap_format(void **ap, struct getbmapx *bmv, int *full) { struct getbmap __user *base = *ap; /* copy only getbmap portion (not getbmapx) */ if (copy_to_user(base, bmv, sizeof(struct getbmap))) return XFS_ERROR(EFAULT); *ap += sizeof(struct getbmap); return 0; } STATIC int |
1da177e4c Linux-2.6.12-rc2 |
1185 |
xfs_ioc_getbmap( |
993386c19 [XFS] decontamina... |
1186 |
struct xfs_inode *ip, |
1da177e4c Linux-2.6.12-rc2 |
1187 1188 1189 1190 |
int ioflags, unsigned int cmd, void __user *arg) { |
8a7141a8b [XFS] convert xfs... |
1191 |
struct getbmapx bmx; |
1da177e4c Linux-2.6.12-rc2 |
1192 |
int error; |
8a7141a8b [XFS] convert xfs... |
1193 |
if (copy_from_user(&bmx, arg, sizeof(struct getbmapx))) |
1da177e4c Linux-2.6.12-rc2 |
1194 |
return -XFS_ERROR(EFAULT); |
8a7141a8b [XFS] convert xfs... |
1195 |
if (bmx.bmv_count < 2) |
1da177e4c Linux-2.6.12-rc2 |
1196 |
return -XFS_ERROR(EINVAL); |
8a7141a8b [XFS] convert xfs... |
1197 |
bmx.bmv_iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0); |
1da177e4c Linux-2.6.12-rc2 |
1198 |
if (ioflags & IO_INVIS) |
8a7141a8b [XFS] convert xfs... |
1199 |
bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ; |
1da177e4c Linux-2.6.12-rc2 |
1200 |
|
8a7141a8b [XFS] convert xfs... |
1201 1202 |
error = xfs_getbmap(ip, &bmx, xfs_getbmap_format, (struct getbmap *)arg+1); |
1da177e4c Linux-2.6.12-rc2 |
1203 1204 |
if (error) return -error; |
8a7141a8b [XFS] convert xfs... |
1205 1206 |
/* copy back header - only size of getbmap */ if (copy_to_user(arg, &bmx, sizeof(struct getbmap))) |
1da177e4c Linux-2.6.12-rc2 |
1207 1208 1209 1210 1211 |
return -XFS_ERROR(EFAULT); return 0; } STATIC int |
8a7141a8b [XFS] convert xfs... |
1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 |
xfs_getbmapx_format(void **ap, struct getbmapx *bmv, int *full) { struct getbmapx __user *base = *ap; if (copy_to_user(base, bmv, sizeof(struct getbmapx))) return XFS_ERROR(EFAULT); *ap += sizeof(struct getbmapx); return 0; } STATIC int |
1da177e4c Linux-2.6.12-rc2 |
1224 |
xfs_ioc_getbmapx( |
993386c19 [XFS] decontamina... |
1225 |
struct xfs_inode *ip, |
1da177e4c Linux-2.6.12-rc2 |
1226 1227 1228 |
void __user *arg) { struct getbmapx bmx; |
1da177e4c Linux-2.6.12-rc2 |
1229 1230 1231 1232 1233 1234 1235 |
int error; if (copy_from_user(&bmx, arg, sizeof(bmx))) return -XFS_ERROR(EFAULT); if (bmx.bmv_count < 2) return -XFS_ERROR(EINVAL); |
8a7141a8b [XFS] convert xfs... |
1236 |
if (bmx.bmv_iflags & (~BMV_IF_VALID)) |
1da177e4c Linux-2.6.12-rc2 |
1237 |
return -XFS_ERROR(EINVAL); |
8a7141a8b [XFS] convert xfs... |
1238 1239 |
error = xfs_getbmap(ip, &bmx, xfs_getbmapx_format, (struct getbmapx *)arg+1); |
1da177e4c Linux-2.6.12-rc2 |
1240 1241 |
if (error) return -error; |
8a7141a8b [XFS] convert xfs... |
1242 1243 |
/* copy back header */ if (copy_to_user(arg, &bmx, sizeof(struct getbmapx))) |
1da177e4c Linux-2.6.12-rc2 |
1244 1245 1246 1247 |
return -XFS_ERROR(EFAULT); return 0; } |
df26cfe84 [XFS] split xfs_i... |
1248 |
|
4d4be482a [XFS] add a FMODE... |
1249 1250 1251 1252 1253 1254 1255 1256 |
/* * Note: some of the ioctl's return positive numbers as a * byte count indicating success, such as readlink_by_handle. * So we don't "sign flip" like most other routines. This means * true errors need to be returned as a negative value. */ long xfs_file_ioctl( |
df26cfe84 [XFS] split xfs_i... |
1257 |
struct file *filp, |
df26cfe84 [XFS] split xfs_i... |
1258 |
unsigned int cmd, |
4d4be482a [XFS] add a FMODE... |
1259 |
unsigned long p) |
df26cfe84 [XFS] split xfs_i... |
1260 1261 |
{ struct inode *inode = filp->f_path.dentry->d_inode; |
4d4be482a [XFS] add a FMODE... |
1262 1263 1264 1265 |
struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; void __user *arg = (void __user *)p; int ioflags = 0; |
df26cfe84 [XFS] split xfs_i... |
1266 |
int error; |
4d4be482a [XFS] add a FMODE... |
1267 1268 |
if (filp->f_mode & FMODE_NOCMTIME) ioflags |= IO_INVIS; |
df26cfe84 [XFS] split xfs_i... |
1269 |
|
cca28fb83 xfs: split xfs_it... |
1270 |
trace_xfs_file_ioctl(ip); |
4d4be482a [XFS] add a FMODE... |
1271 1272 |
switch (cmd) { |
a46db6083 xfs: add FITRIM s... |
1273 1274 |
case FITRIM: return xfs_ioc_trim(mp, arg); |
df26cfe84 [XFS] split xfs_i... |
1275 1276 1277 1278 1279 1280 1281 |
case XFS_IOC_ALLOCSP: case XFS_IOC_FREESP: case XFS_IOC_RESVSP: case XFS_IOC_UNRESVSP: case XFS_IOC_ALLOCSP64: case XFS_IOC_FREESP64: case XFS_IOC_RESVSP64: |
447223520 xfs: Introduce XF... |
1282 1283 |
case XFS_IOC_UNRESVSP64: case XFS_IOC_ZERO_RANGE: { |
743bb4650 [XFS] Move copy_f... |
1284 |
xfs_flock64_t bf; |
df26cfe84 [XFS] split xfs_i... |
1285 |
|
743bb4650 [XFS] Move copy_f... |
1286 1287 1288 1289 |
if (copy_from_user(&bf, arg, sizeof(bf))) return -XFS_ERROR(EFAULT); return xfs_ioc_space(ip, inode, filp, ioflags, cmd, &bf); } |
df26cfe84 [XFS] split xfs_i... |
1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 |
case XFS_IOC_DIOINFO: { struct dioattr da; xfs_buftarg_t *target = XFS_IS_REALTIME_INODE(ip) ? mp->m_rtdev_targp : mp->m_ddev_targp; da.d_mem = da.d_miniosz = 1 << target->bt_sshift; da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1); if (copy_to_user(arg, &da, sizeof(da))) return -XFS_ERROR(EFAULT); return 0; } case XFS_IOC_FSBULKSTAT_SINGLE: case XFS_IOC_FSBULKSTAT: case XFS_IOC_FSINUMBERS: return xfs_ioc_bulkstat(mp, cmd, arg); case XFS_IOC_FSGEOMETRY_V1: return xfs_ioc_fsgeometry_v1(mp, arg); case XFS_IOC_FSGEOMETRY: return xfs_ioc_fsgeometry(mp, arg); case XFS_IOC_GETVERSION: return put_user(inode->i_generation, (int __user *)arg); case XFS_IOC_FSGETXATTR: return xfs_ioc_fsgetxattr(ip, 0, arg); case XFS_IOC_FSGETXATTRA: return xfs_ioc_fsgetxattr(ip, 1, arg); |
65e67f516 [XFS] Fix merge f... |
1322 1323 |
case XFS_IOC_FSSETXATTR: return xfs_ioc_fssetxattr(ip, filp, arg); |
df26cfe84 [XFS] split xfs_i... |
1324 |
case XFS_IOC_GETXFLAGS: |
65e67f516 [XFS] Fix merge f... |
1325 |
return xfs_ioc_getxflags(ip, arg); |
df26cfe84 [XFS] split xfs_i... |
1326 |
case XFS_IOC_SETXFLAGS: |
65e67f516 [XFS] Fix merge f... |
1327 |
return xfs_ioc_setxflags(ip, filp, arg); |
df26cfe84 [XFS] split xfs_i... |
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 |
case XFS_IOC_FSSETDM: { struct fsdmidata dmi; if (copy_from_user(&dmi, arg, sizeof(dmi))) return -XFS_ERROR(EFAULT); error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask, dmi.fsd_dmstate); return -error; } case XFS_IOC_GETBMAP: case XFS_IOC_GETBMAPA: return xfs_ioc_getbmap(ip, ioflags, cmd, arg); case XFS_IOC_GETBMAPX: return xfs_ioc_getbmapx(ip, arg); case XFS_IOC_FD_TO_HANDLE: case XFS_IOC_PATH_TO_HANDLE: |
743bb4650 [XFS] Move copy_f... |
1349 1350 |
case XFS_IOC_PATH_TO_FSHANDLE: { xfs_fsop_handlereq_t hreq; |
df26cfe84 [XFS] split xfs_i... |
1351 |
|
743bb4650 [XFS] Move copy_f... |
1352 1353 1354 1355 1356 1357 |
if (copy_from_user(&hreq, arg, sizeof(hreq))) return -XFS_ERROR(EFAULT); return xfs_find_handle(cmd, &hreq); } case XFS_IOC_OPEN_BY_HANDLE: { xfs_fsop_handlereq_t hreq; |
df26cfe84 [XFS] split xfs_i... |
1358 |
|
743bb4650 [XFS] Move copy_f... |
1359 1360 |
if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) return -XFS_ERROR(EFAULT); |
d296d30a9 xfs: fix dentry a... |
1361 |
return xfs_open_by_handle(filp, &hreq); |
743bb4650 [XFS] Move copy_f... |
1362 |
} |
df26cfe84 [XFS] split xfs_i... |
1363 |
case XFS_IOC_FSSETDM_BY_HANDLE: |
d296d30a9 xfs: fix dentry a... |
1364 |
return xfs_fssetdm_by_handle(filp, arg); |
df26cfe84 [XFS] split xfs_i... |
1365 |
|
743bb4650 [XFS] Move copy_f... |
1366 1367 |
case XFS_IOC_READLINK_BY_HANDLE: { xfs_fsop_handlereq_t hreq; |
df26cfe84 [XFS] split xfs_i... |
1368 |
|
743bb4650 [XFS] Move copy_f... |
1369 1370 |
if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) return -XFS_ERROR(EFAULT); |
d296d30a9 xfs: fix dentry a... |
1371 |
return xfs_readlink_by_handle(filp, &hreq); |
743bb4650 [XFS] Move copy_f... |
1372 |
} |
df26cfe84 [XFS] split xfs_i... |
1373 |
case XFS_IOC_ATTRLIST_BY_HANDLE: |
d296d30a9 xfs: fix dentry a... |
1374 |
return xfs_attrlist_by_handle(filp, arg); |
df26cfe84 [XFS] split xfs_i... |
1375 1376 |
case XFS_IOC_ATTRMULTI_BY_HANDLE: |
d296d30a9 xfs: fix dentry a... |
1377 |
return xfs_attrmulti_by_handle(filp, arg); |
df26cfe84 [XFS] split xfs_i... |
1378 1379 |
case XFS_IOC_SWAPEXT: { |
743bb4650 [XFS] Move copy_f... |
1380 1381 1382 1383 1384 |
struct xfs_swapext sxp; if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t))) return -XFS_ERROR(EFAULT); error = xfs_swapext(&sxp); |
df26cfe84 [XFS] split xfs_i... |
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 |
return -error; } case XFS_IOC_FSCOUNTS: { xfs_fsop_counts_t out; error = xfs_fs_counts(mp, &out); if (error) return -error; if (copy_to_user(arg, &out, sizeof(out))) return -XFS_ERROR(EFAULT); return 0; } case XFS_IOC_SET_RESBLKS: { xfs_fsop_resblks_t inout; __uint64_t in; if (!capable(CAP_SYS_ADMIN)) return -EPERM; |
d5db0f97f xfs: more reserve... |
1406 1407 |
if (mp->m_flags & XFS_MOUNT_RDONLY) return -XFS_ERROR(EROFS); |
df26cfe84 [XFS] split xfs_i... |
1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 |
if (copy_from_user(&inout, arg, sizeof(inout))) return -XFS_ERROR(EFAULT); /* input parameter is passed in resblks field of structure */ in = inout.resblks; error = xfs_reserve_blocks(mp, &in, &inout); if (error) return -error; if (copy_to_user(arg, &inout, sizeof(inout))) return -XFS_ERROR(EFAULT); return 0; } case XFS_IOC_GET_RESBLKS: { xfs_fsop_resblks_t out; if (!capable(CAP_SYS_ADMIN)) return -EPERM; error = xfs_reserve_blocks(mp, NULL, &out); if (error) return -error; if (copy_to_user(arg, &out, sizeof(out))) return -XFS_ERROR(EFAULT); return 0; } case XFS_IOC_FSGROWFSDATA: { xfs_growfs_data_t in; |
df26cfe84 [XFS] split xfs_i... |
1440 1441 1442 1443 1444 1445 1446 1447 1448 |
if (copy_from_user(&in, arg, sizeof(in))) return -XFS_ERROR(EFAULT); error = xfs_growfs_data(mp, &in); return -error; } case XFS_IOC_FSGROWFSLOG: { xfs_growfs_log_t in; |
df26cfe84 [XFS] split xfs_i... |
1449 1450 1451 1452 1453 1454 1455 1456 1457 |
if (copy_from_user(&in, arg, sizeof(in))) return -XFS_ERROR(EFAULT); error = xfs_growfs_log(mp, &in); return -error; } case XFS_IOC_FSGROWFSRT: { xfs_growfs_rt_t in; |
df26cfe84 [XFS] split xfs_i... |
1458 1459 1460 1461 1462 1463 |
if (copy_from_user(&in, arg, sizeof(in))) return -XFS_ERROR(EFAULT); error = xfs_growfs_rt(mp, &in); return -error; } |
df26cfe84 [XFS] split xfs_i... |
1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 |
case XFS_IOC_GOINGDOWN: { __uint32_t in; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(in, (__uint32_t __user *)arg)) return -XFS_ERROR(EFAULT); error = xfs_fs_goingdown(mp, in); return -error; } case XFS_IOC_ERROR_INJECTION: { xfs_error_injection_t in; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (copy_from_user(&in, arg, sizeof(in))) return -XFS_ERROR(EFAULT); error = xfs_errortag_add(in.errtag, mp); return -error; } case XFS_IOC_ERROR_CLEARALL: if (!capable(CAP_SYS_ADMIN)) return -EPERM; error = xfs_errortag_clearall(mp, 1); return -error; default: return -ENOTTY; } } |