aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_ioctl.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c86
1 files changed, 31 insertions, 55 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 98a56568bb24..4c82a050a3a8 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -75,7 +75,6 @@ xfs_find_handle(
75 xfs_handle_t handle; 75 xfs_handle_t handle;
76 xfs_fsop_handlereq_t hreq; 76 xfs_fsop_handlereq_t hreq;
77 struct inode *inode; 77 struct inode *inode;
78 bhv_vnode_t *vp;
79 78
80 if (copy_from_user(&hreq, arg, sizeof(hreq))) 79 if (copy_from_user(&hreq, arg, sizeof(hreq)))
81 return -XFS_ERROR(EFAULT); 80 return -XFS_ERROR(EFAULT);
@@ -134,21 +133,16 @@ xfs_find_handle(
134 return -XFS_ERROR(EBADF); 133 return -XFS_ERROR(EBADF);
135 } 134 }
136 135
137 /* we need the vnode */
138 vp = vn_from_inode(inode);
139
140 /* now we can grab the fsid */ 136 /* now we can grab the fsid */
141 memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid, 137 memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid,
142 sizeof(xfs_fsid_t)); 138 sizeof(xfs_fsid_t));
143 hsize = sizeof(xfs_fsid_t); 139 hsize = sizeof(xfs_fsid_t);
144 140
145 if (cmd != XFS_IOC_PATH_TO_FSHANDLE) { 141 if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
146 xfs_inode_t *ip; 142 xfs_inode_t *ip = XFS_I(inode);
147 int lock_mode; 143 int lock_mode;
148 144
149 /* need to get access to the xfs_inode to read the generation */ 145 /* need to get access to the xfs_inode to read the generation */
150 ip = xfs_vtoi(vp);
151 ASSERT(ip);
152 lock_mode = xfs_ilock_map_shared(ip); 146 lock_mode = xfs_ilock_map_shared(ip);
153 147
154 /* fill in fid section of handle from inode */ 148 /* fill in fid section of handle from inode */
@@ -176,21 +170,19 @@ xfs_find_handle(
176 170
177 171
178/* 172/*
179 * Convert userspace handle data into vnode (and inode). 173 * Convert userspace handle data into inode.
180 * We [ab]use the fact that all the fsop_handlereq ioctl calls 174 *
181 * have a data structure argument whose first component is always 175 * We use the fact that all the fsop_handlereq ioctl calls have a data
182 * a xfs_fsop_handlereq_t, so we can cast to and from this type. 176 * structure argument whose first component is always a xfs_fsop_handlereq_t,
183 * This allows us to optimise the copy_from_user calls and gives 177 * so we can pass that sub structure into this handy, shared routine.
184 * a handy, shared routine.
185 * 178 *
186 * If no error, caller must always VN_RELE the returned vp. 179 * If no error, caller must always iput the returned inode.
187 */ 180 */
188STATIC int 181STATIC int
189xfs_vget_fsop_handlereq( 182xfs_vget_fsop_handlereq(
190 xfs_mount_t *mp, 183 xfs_mount_t *mp,
191 struct inode *parinode, /* parent inode pointer */ 184 struct inode *parinode, /* parent inode pointer */
192 xfs_fsop_handlereq_t *hreq, 185 xfs_fsop_handlereq_t *hreq,
193 bhv_vnode_t **vp,
194 struct inode **inode) 186 struct inode **inode)
195{ 187{
196 void __user *hanp; 188 void __user *hanp;
@@ -199,8 +191,6 @@ xfs_vget_fsop_handlereq(
199 xfs_handle_t *handlep; 191 xfs_handle_t *handlep;
200 xfs_handle_t handle; 192 xfs_handle_t handle;
201 xfs_inode_t *ip; 193 xfs_inode_t *ip;
202 struct inode *inodep;
203 bhv_vnode_t *vpp;
204 xfs_ino_t ino; 194 xfs_ino_t ino;
205 __u32 igen; 195 __u32 igen;
206 int error; 196 int error;
@@ -241,7 +231,7 @@ xfs_vget_fsop_handlereq(
241 } 231 }
242 232
243 /* 233 /*
244 * Get the XFS inode, building a vnode to go with it. 234 * Get the XFS inode, building a Linux inode to go with it.
245 */ 235 */
246 error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0); 236 error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
247 if (error) 237 if (error)
@@ -253,12 +243,9 @@ xfs_vget_fsop_handlereq(
253 return XFS_ERROR(ENOENT); 243 return XFS_ERROR(ENOENT);
254 } 244 }
255 245
256 vpp = XFS_ITOV(ip);
257 inodep = vn_to_inode(vpp);
258 xfs_iunlock(ip, XFS_ILOCK_SHARED); 246 xfs_iunlock(ip, XFS_ILOCK_SHARED);
259 247
260 *vp = vpp; 248 *inode = XFS_ITOV(ip);
261 *inode = inodep;
262 return 0; 249 return 0;
263} 250}
264 251
@@ -275,7 +262,6 @@ xfs_open_by_handle(
275 struct file *filp; 262 struct file *filp;
276 struct inode *inode; 263 struct inode *inode;
277 struct dentry *dentry; 264 struct dentry *dentry;
278 bhv_vnode_t *vp;
279 xfs_fsop_handlereq_t hreq; 265 xfs_fsop_handlereq_t hreq;
280 266
281 if (!capable(CAP_SYS_ADMIN)) 267 if (!capable(CAP_SYS_ADMIN))
@@ -283,7 +269,7 @@ xfs_open_by_handle(
283 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) 269 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
284 return -XFS_ERROR(EFAULT); 270 return -XFS_ERROR(EFAULT);
285 271
286 error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &vp, &inode); 272 error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode);
287 if (error) 273 if (error)
288 return -error; 274 return -error;
289 275
@@ -385,7 +371,6 @@ xfs_readlink_by_handle(
385{ 371{
386 struct inode *inode; 372 struct inode *inode;
387 xfs_fsop_handlereq_t hreq; 373 xfs_fsop_handlereq_t hreq;
388 bhv_vnode_t *vp;
389 __u32 olen; 374 __u32 olen;
390 void *link; 375 void *link;
391 int error; 376 int error;
@@ -395,7 +380,7 @@ xfs_readlink_by_handle(
395 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) 380 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
396 return -XFS_ERROR(EFAULT); 381 return -XFS_ERROR(EFAULT);
397 382
398 error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &vp, &inode); 383 error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode);
399 if (error) 384 if (error)
400 return -error; 385 return -error;
401 386
@@ -438,34 +423,32 @@ xfs_fssetdm_by_handle(
438 struct fsdmidata fsd; 423 struct fsdmidata fsd;
439 xfs_fsop_setdm_handlereq_t dmhreq; 424 xfs_fsop_setdm_handlereq_t dmhreq;
440 struct inode *inode; 425 struct inode *inode;
441 bhv_vnode_t *vp;
442 426
443 if (!capable(CAP_MKNOD)) 427 if (!capable(CAP_MKNOD))
444 return -XFS_ERROR(EPERM); 428 return -XFS_ERROR(EPERM);
445 if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t))) 429 if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t)))
446 return -XFS_ERROR(EFAULT); 430 return -XFS_ERROR(EFAULT);
447 431
448 error = xfs_vget_fsop_handlereq(mp, parinode, &dmhreq.hreq, &vp, &inode); 432 error = xfs_vget_fsop_handlereq(mp, parinode, &dmhreq.hreq, &inode);
449 if (error) 433 if (error)
450 return -error; 434 return -error;
451 435
452 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { 436 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
453 VN_RELE(vp); 437 error = -XFS_ERROR(EPERM);
454 return -XFS_ERROR(EPERM); 438 goto out;
455 } 439 }
456 440
457 if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) { 441 if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) {
458 VN_RELE(vp); 442 error = -XFS_ERROR(EFAULT);
459 return -XFS_ERROR(EFAULT); 443 goto out;
460 } 444 }
461 445
462 error = xfs_set_dmattrs(xfs_vtoi(vp), 446 error = -xfs_set_dmattrs(XFS_I(inode), fsd.fsd_dmevmask,
463 fsd.fsd_dmevmask, fsd.fsd_dmstate); 447 fsd.fsd_dmstate);
464 448
465 VN_RELE(vp); 449 out:
466 if (error) 450 iput(inode);
467 return -error; 451 return error;
468 return 0;
469} 452}
470 453
471STATIC int 454STATIC int
@@ -478,7 +461,6 @@ xfs_attrlist_by_handle(
478 attrlist_cursor_kern_t *cursor; 461 attrlist_cursor_kern_t *cursor;
479 xfs_fsop_attrlist_handlereq_t al_hreq; 462 xfs_fsop_attrlist_handlereq_t al_hreq;
480 struct inode *inode; 463 struct inode *inode;
481 bhv_vnode_t *vp;
482 char *kbuf; 464 char *kbuf;
483 465
484 if (!capable(CAP_SYS_ADMIN)) 466 if (!capable(CAP_SYS_ADMIN))
@@ -488,8 +470,7 @@ xfs_attrlist_by_handle(
488 if (al_hreq.buflen > XATTR_LIST_MAX) 470 if (al_hreq.buflen > XATTR_LIST_MAX)
489 return -XFS_ERROR(EINVAL); 471 return -XFS_ERROR(EINVAL);
490 472
491 error = xfs_vget_fsop_handlereq(mp, parinode, &al_hreq.hreq, 473 error = xfs_vget_fsop_handlereq(mp, parinode, &al_hreq.hreq, &inode);
492 &vp, &inode);
493 if (error) 474 if (error)
494 goto out; 475 goto out;
495 476
@@ -509,7 +490,7 @@ xfs_attrlist_by_handle(
509 out_kfree: 490 out_kfree:
510 kfree(kbuf); 491 kfree(kbuf);
511 out_vn_rele: 492 out_vn_rele:
512 VN_RELE(vp); 493 iput(inode);
513 out: 494 out:
514 return -error; 495 return -error;
515} 496}
@@ -531,7 +512,7 @@ xfs_attrmulti_attr_get(
531 if (!kbuf) 512 if (!kbuf)
532 return ENOMEM; 513 return ENOMEM;
533 514
534 error = xfs_attr_get(XFS_I(inode), name, kbuf, len, flags, NULL); 515 error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags, NULL);
535 if (error) 516 if (error)
536 goto out_kfree; 517 goto out_kfree;
537 518
@@ -598,7 +579,6 @@ xfs_attrmulti_by_handle(
598 xfs_attr_multiop_t *ops; 579 xfs_attr_multiop_t *ops;
599 xfs_fsop_attrmulti_handlereq_t am_hreq; 580 xfs_fsop_attrmulti_handlereq_t am_hreq;
600 struct inode *inode; 581 struct inode *inode;
601 bhv_vnode_t *vp;
602 unsigned int i, size; 582 unsigned int i, size;
603 char *attr_name; 583 char *attr_name;
604 584
@@ -607,7 +587,7 @@ xfs_attrmulti_by_handle(
607 if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t))) 587 if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
608 return -XFS_ERROR(EFAULT); 588 return -XFS_ERROR(EFAULT);
609 589
610 error = xfs_vget_fsop_handlereq(mp, parinode, &am_hreq.hreq, &vp, &inode); 590 error = xfs_vget_fsop_handlereq(mp, parinode, &am_hreq.hreq, &inode);
611 if (error) 591 if (error)
612 goto out; 592 goto out;
613 593
@@ -666,7 +646,7 @@ xfs_attrmulti_by_handle(
666 out_kfree_ops: 646 out_kfree_ops:
667 kfree(ops); 647 kfree(ops);
668 out_vn_rele: 648 out_vn_rele:
669 VN_RELE(vp); 649 iput(inode);
670 out: 650 out:
671 return -error; 651 return -error;
672} 652}
@@ -702,7 +682,6 @@ xfs_ioc_fsgeometry(
702 682
703STATIC int 683STATIC int
704xfs_ioc_xattr( 684xfs_ioc_xattr(
705 bhv_vnode_t *vp,
706 xfs_inode_t *ip, 685 xfs_inode_t *ip,
707 struct file *filp, 686 struct file *filp,
708 unsigned int cmd, 687 unsigned int cmd,
@@ -735,12 +714,10 @@ xfs_ioctl(
735 void __user *arg) 714 void __user *arg)
736{ 715{
737 struct inode *inode = filp->f_path.dentry->d_inode; 716 struct inode *inode = filp->f_path.dentry->d_inode;
738 bhv_vnode_t *vp = vn_from_inode(inode);
739 xfs_mount_t *mp = ip->i_mount; 717 xfs_mount_t *mp = ip->i_mount;
740 int error; 718 int error;
741 719
742 vn_trace_entry(XFS_I(inode), "xfs_ioctl", (inst_t *)__return_address); 720 xfs_itrace_entry(XFS_I(inode));
743
744 switch (cmd) { 721 switch (cmd) {
745 722
746 case XFS_IOC_ALLOCSP: 723 case XFS_IOC_ALLOCSP:
@@ -764,7 +741,7 @@ xfs_ioctl(
764 case XFS_IOC_DIOINFO: { 741 case XFS_IOC_DIOINFO: {
765 struct dioattr da; 742 struct dioattr da;
766 xfs_buftarg_t *target = 743 xfs_buftarg_t *target =
767 (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? 744 XFS_IS_REALTIME_INODE(ip) ?
768 mp->m_rtdev_targp : mp->m_ddev_targp; 745 mp->m_rtdev_targp : mp->m_ddev_targp;
769 746
770 da.d_mem = da.d_miniosz = 1 << target->bt_sshift; 747 da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
@@ -796,7 +773,7 @@ xfs_ioctl(
796 case XFS_IOC_GETXFLAGS: 773 case XFS_IOC_GETXFLAGS:
797 case XFS_IOC_SETXFLAGS: 774 case XFS_IOC_SETXFLAGS:
798 case XFS_IOC_FSSETXATTR: 775 case XFS_IOC_FSSETXATTR:
799 return xfs_ioc_xattr(vp, ip, filp, cmd, arg); 776 return xfs_ioc_xattr(ip, filp, cmd, arg);
800 777
801 case XFS_IOC_FSSETDM: { 778 case XFS_IOC_FSSETDM: {
802 struct fsdmidata dmi; 779 struct fsdmidata dmi;
@@ -1203,7 +1180,6 @@ xfs_ioc_fsgetxattr(
1203 1180
1204STATIC int 1181STATIC int
1205xfs_ioc_xattr( 1182xfs_ioc_xattr(
1206 bhv_vnode_t *vp,
1207 xfs_inode_t *ip, 1183 xfs_inode_t *ip,
1208 struct file *filp, 1184 struct file *filp,
1209 unsigned int cmd, 1185 unsigned int cmd,
@@ -1237,7 +1213,7 @@ xfs_ioc_xattr(
1237 1213
1238 error = xfs_setattr(ip, vattr, attr_flags, NULL); 1214 error = xfs_setattr(ip, vattr, attr_flags, NULL);
1239 if (likely(!error)) 1215 if (likely(!error))
1240 __vn_revalidate(vp, vattr); /* update flags */ 1216 vn_revalidate(XFS_ITOV(ip)); /* update flags */
1241 error = -error; 1217 error = -error;
1242 break; 1218 break;
1243 } 1219 }
@@ -1272,7 +1248,7 @@ xfs_ioc_xattr(
1272 1248
1273 error = xfs_setattr(ip, vattr, attr_flags, NULL); 1249 error = xfs_setattr(ip, vattr, attr_flags, NULL);
1274 if (likely(!error)) 1250 if (likely(!error))
1275 __vn_revalidate(vp, vattr); /* update flags */ 1251 vn_revalidate(XFS_ITOV(ip)); /* update flags */
1276 error = -error; 1252 error = -error;
1277 break; 1253 break;
1278 } 1254 }