ext2_vnops.c (198940) | ext2_vnops.c (202283) |
---|---|
1/*- 2 * modified for EXT2FS support in Lites 1.1 3 * 4 * Aug 1995, Godmar Back (gback@cs.utah.edu) 5 * University of Utah, Department of Computer Science 6 */ 7/*- 8 * Copyright (c) 1982, 1986, 1989, 1993 --- 25 unchanged lines hidden (view full) --- 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)ufs_vnops.c 8.7 (Berkeley) 2/3/94 41 * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 | 1/*- 2 * modified for EXT2FS support in Lites 1.1 3 * 4 * Aug 1995, Godmar Back (gback@cs.utah.edu) 5 * University of Utah, Department of Computer Science 6 */ 7/*- 8 * Copyright (c) 1982, 1986, 1989, 1993 --- 25 unchanged lines hidden (view full) --- 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)ufs_vnops.c 8.7 (Berkeley) 2/3/94 41 * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 |
42 * $FreeBSD: head/sys/gnu/fs/ext2fs/ext2_vnops.c 198940 2009-11-05 04:51:38Z jh $ | 42 * $FreeBSD: head/sys/fs/ext2fs/ext2_vnops.c 202283 2010-01-14 14:30:54Z lulf $ |
43 */ 44 45#include "opt_suiddir.h" 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/resourcevar.h> 50#include <sys/kernel.h> --- 18 unchanged lines hidden (view full) --- 69#include <vm/vm_extern.h> 70#include <vm/vnode_pager.h> 71 72#include <fs/fifofs/fifo.h> 73 74#include <sys/signalvar.h> 75#include <ufs/ufs/dir.h> 76 | 43 */ 44 45#include "opt_suiddir.h" 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/resourcevar.h> 50#include <sys/kernel.h> --- 18 unchanged lines hidden (view full) --- 69#include <vm/vm_extern.h> 70#include <vm/vnode_pager.h> 71 72#include <fs/fifofs/fifo.h> 73 74#include <sys/signalvar.h> 75#include <ufs/ufs/dir.h> 76 |
77#include <gnu/fs/ext2fs/inode.h> 78#include <gnu/fs/ext2fs/ext2_mount.h> 79#include <gnu/fs/ext2fs/ext2_fs_sb.h> 80#include <gnu/fs/ext2fs/fs.h> 81#include <gnu/fs/ext2fs/ext2_extern.h> 82#include <gnu/fs/ext2fs/ext2_fs.h> | 77#include 78#include 79#include <fs/ext2fs/fs.h> 80#include <fs/ext2fs/ext2_extern.h> 81#include <fs/ext2fs/ext2fs.h> 82#include <fs/ext2fs/ext2_dir.h> |
83 84static int ext2_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *); | 83 84static int ext2_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *); |
85static void ext2_itimes_locked(struct vnode *); |
|
85 86static vop_access_t ext2_access; 87static int ext2_chmod(struct vnode *, int, struct ucred *, struct thread *); 88static int ext2_chown(struct vnode *, uid_t, gid_t, struct ucred *, 89 struct thread *); 90static vop_close_t ext2_close; 91static vop_create_t ext2_create; 92static vop_fsync_t ext2_fsync; --- 62 unchanged lines hidden (view full) --- 155 .vop_print = ext2_print, 156 .vop_read = VOP_PANIC, 157 .vop_reclaim = ext2_reclaim, 158 .vop_setattr = ext2_setattr, 159 .vop_write = VOP_PANIC, 160 .vop_vptofh = ext2_vptofh, 161}; 162 | 86 87static vop_access_t ext2_access; 88static int ext2_chmod(struct vnode *, int, struct ucred *, struct thread *); 89static int ext2_chown(struct vnode *, uid_t, gid_t, struct ucred *, 90 struct thread *); 91static vop_close_t ext2_close; 92static vop_create_t ext2_create; 93static vop_fsync_t ext2_fsync; --- 62 unchanged lines hidden (view full) --- 156 .vop_print = ext2_print, 157 .vop_read = VOP_PANIC, 158 .vop_reclaim = ext2_reclaim, 159 .vop_setattr = ext2_setattr, 160 .vop_write = VOP_PANIC, 161 .vop_vptofh = ext2_vptofh, 162}; 163 |
163#include <gnu/fs/ext2fs/ext2_readwrite.c> | 164#include |
164 165/* 166 * A virgin directory (no blushing please). 167 * Note that the type and namlen fields are reversed relative to ext2. 168 * Also, we don't use `struct odirtemplate', since it would just cause 169 * endianness problems. 170 */ 171static struct dirtemplate mastertemplate = { 172 0, 12, 1, EXT2_FT_DIR, ".", 173 0, DIRBLKSIZ - 12, 2, EXT2_FT_DIR, ".." 174}; 175static struct dirtemplate omastertemplate = { 176 0, 12, 1, EXT2_FT_UNKNOWN, ".", 177 0, DIRBLKSIZ - 12, 2, EXT2_FT_UNKNOWN, ".." 178}; 179 | 165 166/* 167 * A virgin directory (no blushing please). 168 * Note that the type and namlen fields are reversed relative to ext2. 169 * Also, we don't use `struct odirtemplate', since it would just cause 170 * endianness problems. 171 */ 172static struct dirtemplate mastertemplate = { 173 0, 12, 1, EXT2_FT_DIR, ".", 174 0, DIRBLKSIZ - 12, 2, EXT2_FT_DIR, ".." 175}; 176static struct dirtemplate omastertemplate = { 177 0, 12, 1, EXT2_FT_UNKNOWN, ".", 178 0, DIRBLKSIZ - 12, 2, EXT2_FT_UNKNOWN, ".." 179}; 180 |
180void 181ext2_itimes(vp) 182 struct vnode *vp; | 181static void 182ext2_itimes_locked(struct vnode *vp) |
183{ 184 struct inode *ip; 185 struct timespec ts; 186 | 183{ 184 struct inode *ip; 185 struct timespec ts; 186 |
187 ASSERT_VI_LOCKED(vp, __func__); 188 |
|
187 ip = VTOI(vp); 188 if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0) 189 return; 190 if ((vp->v_type == VBLK || vp->v_type == VCHR)) 191 ip->i_flag |= IN_LAZYMOD; 192 else 193 ip->i_flag |= IN_MODIFIED; 194 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { --- 10 unchanged lines hidden (view full) --- 205 if (ip->i_flag & IN_CHANGE) { 206 ip->i_ctime = ts.tv_sec; 207 ip->i_ctimensec = ts.tv_nsec; 208 } 209 } 210 ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); 211} 212 | 189 ip = VTOI(vp); 190 if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0) 191 return; 192 if ((vp->v_type == VBLK || vp->v_type == VCHR)) 193 ip->i_flag |= IN_LAZYMOD; 194 else 195 ip->i_flag |= IN_MODIFIED; 196 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { --- 10 unchanged lines hidden (view full) --- 207 if (ip->i_flag & IN_CHANGE) { 208 ip->i_ctime = ts.tv_sec; 209 ip->i_ctimensec = ts.tv_nsec; 210 } 211 } 212 ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); 213} 214 |
215void 216ext2_itimes(struct vnode *vp) 217{ 218 219 VI_LOCK(vp); 220 ext2_itimes_locked(vp); 221 VI_UNLOCK(vp); 222} 223 |
|
213/* 214 * Create a regular file 215 */ 216static int 217ext2_create(ap) 218 struct vop_create_args /* { 219 struct vnode *a_dvp; 220 struct vnode **a_vpp; --- 49 unchanged lines hidden (view full) --- 270 struct ucred *a_cred; 271 struct thread *a_td; 272 } */ *ap; 273{ 274 struct vnode *vp = ap->a_vp; 275 276 VI_LOCK(vp); 277 if (vp->v_usecount > 1) | 224/* 225 * Create a regular file 226 */ 227static int 228ext2_create(ap) 229 struct vop_create_args /* { 230 struct vnode *a_dvp; 231 struct vnode **a_vpp; --- 49 unchanged lines hidden (view full) --- 281 struct ucred *a_cred; 282 struct thread *a_td; 283 } */ *ap; 284{ 285 struct vnode *vp = ap->a_vp; 286 287 VI_LOCK(vp); 288 if (vp->v_usecount > 1) |
278 ext2_itimes(vp); | 289 ext2_itimes_locked(vp); |
279 VI_UNLOCK(vp); 280 return (0); 281} 282 283static int 284ext2_access(ap) 285 struct vop_access_args /* { 286 struct vnode *a_vp; --- 24 unchanged lines hidden (view full) --- 311 return (EROFS); 312 break; 313 default: 314 break; 315 } 316 } 317 318 /* If immutable bit set, nobody gets to write it. */ | 290 VI_UNLOCK(vp); 291 return (0); 292} 293 294static int 295ext2_access(ap) 296 struct vop_access_args /* { 297 struct vnode *a_vp; --- 24 unchanged lines hidden (view full) --- 322 return (EROFS); 323 break; 324 default: 325 break; 326 } 327 } 328 329 /* If immutable bit set, nobody gets to write it. */ |
319 if ((accmode & VWRITE) && (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT))) | 330 if ((accmode & VWRITE) && (ip->i_flags & (SF_IMMUTABLE | SF_SNAPSHOT))) |
320 return (EPERM); 321 322 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid, 323 ap->a_accmode, ap->a_cred, NULL); 324 return (error); 325} 326 327static int --- 58 unchanged lines hidden (view full) --- 386 */ 387 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || 388 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || 389 (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || 390 ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { 391 return (EINVAL); 392 } 393 if (vap->va_flags != VNOVAL) { | 331 return (EPERM); 332 333 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid, 334 ap->a_accmode, ap->a_cred, NULL); 335 return (error); 336} 337 338static int --- 58 unchanged lines hidden (view full) --- 397 */ 398 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || 399 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || 400 (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || 401 ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { 402 return (EINVAL); 403 } 404 if (vap->va_flags != VNOVAL) { |
394 /* Disallow flags not supported by ext2fs. */ 395 if (vap->va_flags & ~(SF_APPEND | SF_IMMUTABLE | UF_NODUMP)) 396 return (EOPNOTSUPP); 397 | |
398 if (vp->v_mount->mnt_flag & MNT_RDONLY) 399 return (EROFS); | 405 if (vp->v_mount->mnt_flag & MNT_RDONLY) 406 return (EROFS); |
407 /* Disallow flags not supported by ext2fs. */ 408 if(vap->va_flags & ~(SF_APPEND | SF_IMMUTABLE | UF_NODUMP)) 409 return(EOPNOTSUPP); |
|
400 /* 401 * Callers may only modify the file flags on objects they 402 * have VADMIN rights for. 403 */ 404 if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) 405 return (error); 406 /* 407 * Unprivileged processes and privileged processes in --- 7 unchanged lines hidden (view full) --- 415 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) { 416 error = securelevel_gt(cred, 0); 417 if (error) 418 return (error); 419 } 420 ip->i_flags = vap->va_flags; 421 } else { 422 if (ip->i_flags | 410 /* 411 * Callers may only modify the file flags on objects they 412 * have VADMIN rights for. 413 */ 414 if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) 415 return (error); 416 /* 417 * Unprivileged processes and privileged processes in --- 7 unchanged lines hidden (view full) --- 425 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) { 426 error = securelevel_gt(cred, 0); 427 if (error) 428 return (error); 429 } 430 ip->i_flags = vap->va_flags; 431 } else { 432 if (ip->i_flags |
423 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND) || 424 (vap->va_flags & UF_SETTABLE) != vap->va_flags) | 433 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) |
425 return (EPERM); 426 ip->i_flags &= SF_SETTABLE; | 434 return (EPERM); 435 ip->i_flags &= SF_SETTABLE; |
427 ip->i_flags |= (vap->va_flags & UF_SETTABLE); | |
428 } 429 ip->i_flag |= IN_CHANGE; 430 if (vap->va_flags & (IMMUTABLE | APPEND)) 431 return (0); 432 } 433 if (ip->i_flags & (IMMUTABLE | APPEND)) 434 return (EPERM); 435 /* --- 169 unchanged lines hidden (view full) --- 605 struct ucred *a_cred; 606 int a_waitfor; 607 struct thread *a_td; 608 } */ *ap; 609{ 610 /* 611 * Flush all dirty buffers associated with a vnode. 612 */ | 436 } 437 ip->i_flag |= IN_CHANGE; 438 if (vap->va_flags & (IMMUTABLE | APPEND)) 439 return (0); 440 } 441 if (ip->i_flags & (IMMUTABLE | APPEND)) 442 return (EPERM); 443 /* --- 169 unchanged lines hidden (view full) --- 613 struct ucred *a_cred; 614 int a_waitfor; 615 struct thread *a_td; 616 } */ *ap; 617{ 618 /* 619 * Flush all dirty buffers associated with a vnode. 620 */ |
613 ext2_discard_prealloc(VTOI(ap->a_vp)); | |
614 615 vop_stdfsync(ap); 616 617 return (ext2_update(ap->a_vp, ap->a_waitfor == MNT_WAIT)); 618} 619 620/* 621 * Mknod vnode call --- 116 unchanged lines hidden (view full) --- 738 ip->i_flag |= IN_CHANGE; 739 } 740out: 741 return (error); 742} 743 744/* 745 * Rename system call. | 621 622 vop_stdfsync(ap); 623 624 return (ext2_update(ap->a_vp, ap->a_waitfor == MNT_WAIT)); 625} 626 627/* 628 * Mknod vnode call --- 116 unchanged lines hidden (view full) --- 745 ip->i_flag |= IN_CHANGE; 746 } 747out: 748 return (error); 749} 750 751/* 752 * Rename system call. |
746 * See comments in sys/ufs/ufs/ufs_vnops.c | 753 * rename("foo", "bar"); 754 * is essentially 755 * unlink("bar"); 756 * link("foo", "bar"); 757 * unlink("foo"); 758 * but ``atomically''. Can't do full commit without saving state in the 759 * inode on disk which isn't feasible at this time. Best we can do is 760 * always guarantee the target exists. 761 * 762 * Basic algorithm is: 763 * 764 * 1) Bump link count on source while we're linking it to the 765 * target. This also ensure the inode won't be deleted out 766 * from underneath us while we work (it may be truncated by 767 * a concurrent `trunc' or `open' for creation). 768 * 2) Link source to destination. If destination already exists, 769 * delete it first. 770 * 3) Unlink source reference to inode if still around. If a 771 * directory was moved and the parent of the destination 772 * is different from the source, patch the ".." entry in the 773 * directory. |
747 */ 748static int 749ext2_rename(ap) 750 struct vop_rename_args /* { 751 struct vnode *a_fdvp; 752 struct vnode *a_fvp; 753 struct componentname *a_fcnp; 754 struct vnode *a_tdvp; --- 429 unchanged lines hidden (view full) --- 1184 dp->i_nlink++; 1185 dp->i_flag |= IN_CHANGE; 1186 error = ext2_update(dvp, 1); 1187 if (error) 1188 goto bad; 1189 1190 /* Initialize directory with "." and ".." from static template. */ 1191 if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs, | 774 */ 775static int 776ext2_rename(ap) 777 struct vop_rename_args /* { 778 struct vnode *a_fdvp; 779 struct vnode *a_fvp; 780 struct componentname *a_fcnp; 781 struct vnode *a_tdvp; --- 429 unchanged lines hidden (view full) --- 1211 dp->i_nlink++; 1212 dp->i_flag |= IN_CHANGE; 1213 error = ext2_update(dvp, 1); 1214 if (error) 1215 goto bad; 1216 1217 /* Initialize directory with "." and ".." from static template. */ 1218 if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs, |
1192 EXT2_FEATURE_INCOMPAT_FILETYPE)) | 1219 EXT2F_INCOMPAT_FTYPE)) |
1193 dtp = &mastertemplate; 1194 else 1195 dtp = &omastertemplate; 1196 dirtemplate = *dtp; 1197 dirtemplate.dot_ino = ip->i_number; 1198 dirtemplate.dotdot_ino = dp->i_number; 1199 /* note that in ext2 DIRBLKSIZ == blocksize, not DEV_BSIZE 1200 * so let's just redefine it - for this function only 1201 */ 1202#undef DIRBLKSIZ | 1220 dtp = &mastertemplate; 1221 else 1222 dtp = &omastertemplate; 1223 dirtemplate = *dtp; 1224 dirtemplate.dot_ino = ip->i_number; 1225 dirtemplate.dotdot_ino = dp->i_number; 1226 /* note that in ext2 DIRBLKSIZ == blocksize, not DEV_BSIZE 1227 * so let's just redefine it - for this function only 1228 */ 1229#undef DIRBLKSIZ |
1203#define DIRBLKSIZ VTOI(dvp)->i_e2fs->s_blocksize | 1230#define DIRBLKSIZ VTOI(dvp)->i_e2fs->e2fs_bsize |
1204 dirtemplate.dotdot_reclen = DIRBLKSIZ - 12; 1205 error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate, 1206 sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE, 1207 IO_NODELOCKED | IO_SYNC | IO_NOMACCHECK, cnp->cn_cred, NOCRED, 1208 NULL, NULL); 1209 if (error) { 1210 dp->i_nlink--; 1211 dp->i_flag |= IN_CHANGE; --- 237 unchanged lines hidden (view full) --- 1449 struct ucred *a_cred; 1450 struct thread *a_td; 1451 } */ *ap; 1452{ 1453 struct vnode *vp = ap->a_vp; 1454 1455 VI_LOCK(vp); 1456 if (vp->v_usecount > 1) | 1231 dirtemplate.dotdot_reclen = DIRBLKSIZ - 12; 1232 error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate, 1233 sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE, 1234 IO_NODELOCKED | IO_SYNC | IO_NOMACCHECK, cnp->cn_cred, NOCRED, 1235 NULL, NULL); 1236 if (error) { 1237 dp->i_nlink--; 1238 dp->i_flag |= IN_CHANGE; --- 237 unchanged lines hidden (view full) --- 1476 struct ucred *a_cred; 1477 struct thread *a_td; 1478 } */ *ap; 1479{ 1480 struct vnode *vp = ap->a_vp; 1481 1482 VI_LOCK(vp); 1483 if (vp->v_usecount > 1) |
1457 ext2_itimes(vp); | 1484 ext2_itimes_locked(vp); |
1458 VI_UNLOCK(vp); 1459 return (fifo_specops.vop_close(ap)); 1460} 1461 1462/* 1463 * Kqfilter wrapper for fifos. 1464 * 1465 * Fall through to ext2 kqfilter routines if needed --- 184 unchanged lines hidden --- | 1485 VI_UNLOCK(vp); 1486 return (fifo_specops.vop_close(ap)); 1487} 1488 1489/* 1490 * Kqfilter wrapper for fifos. 1491 * 1492 * Fall through to ext2 kqfilter routines if needed --- 184 unchanged lines hidden --- |