aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h4
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c145
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c29
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.h8
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c56
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c11
-rw-r--r--fs/xfs/xfs_buf_item.c4
-rw-r--r--fs/xfs/xfs_inode.c4
-rw-r--r--fs/xfs/xfs_inode.h17
-rw-r--r--fs/xfs/xfs_log_recover.c26
-rw-r--r--fs/xfs/xfs_mount.h4
-rw-r--r--fs/xfs/xfs_rename.c49
-rw-r--r--fs/xfs/xfs_rw.c2
-rw-r--r--fs/xfs/xfs_sb.h1
-rw-r--r--fs/xfs/xfs_vnodeops.c149
-rw-r--r--fs/xfs/xfs_vnodeops.h2
-rw-r--r--include/linux/fs.h8
19 files changed, 149 insertions, 375 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index aae8d0768eca..cb329edc925b 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -1085,7 +1085,7 @@ xfs_bawrite(
1085 bp->b_flags &= ~(XBF_READ | XBF_DELWRI | XBF_READ_AHEAD); 1085 bp->b_flags &= ~(XBF_READ | XBF_DELWRI | XBF_READ_AHEAD);
1086 bp->b_flags |= (XBF_WRITE | XBF_ASYNC | _XBF_RUN_QUEUES); 1086 bp->b_flags |= (XBF_WRITE | XBF_ASYNC | _XBF_RUN_QUEUES);
1087 1087
1088 bp->b_fspriv3 = mp; 1088 bp->b_mount = mp;
1089 bp->b_strat = xfs_bdstrat_cb; 1089 bp->b_strat = xfs_bdstrat_cb;
1090 return xfs_bdstrat_cb(bp); 1090 return xfs_bdstrat_cb(bp);
1091} 1091}
@@ -1098,7 +1098,7 @@ xfs_bdwrite(
1098 XB_TRACE(bp, "bdwrite", 0); 1098 XB_TRACE(bp, "bdwrite", 0);
1099 1099
1100 bp->b_strat = xfs_bdstrat_cb; 1100 bp->b_strat = xfs_bdstrat_cb;
1101 bp->b_fspriv3 = mp; 1101 bp->b_mount = mp;
1102 1102
1103 bp->b_flags &= ~XBF_READ; 1103 bp->b_flags &= ~XBF_READ;
1104 bp->b_flags |= (XBF_DELWRI | XBF_ASYNC); 1104 bp->b_flags |= (XBF_DELWRI | XBF_ASYNC);
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 0e2aa16f5e41..af8764e02d78 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -168,7 +168,7 @@ typedef struct xfs_buf {
168 struct completion b_iowait; /* queue for I/O waiters */ 168 struct completion b_iowait; /* queue for I/O waiters */
169 void *b_fspriv; 169 void *b_fspriv;
170 void *b_fspriv2; 170 void *b_fspriv2;
171 void *b_fspriv3; 171 struct xfs_mount *b_mount;
172 unsigned short b_error; /* error code on I/O */ 172 unsigned short b_error; /* error code on I/O */
173 unsigned int b_page_count; /* size of page array */ 173 unsigned int b_page_count; /* size of page array */
174 unsigned int b_offset; /* page offset in first page */ 174 unsigned int b_offset; /* page offset in first page */
@@ -335,8 +335,6 @@ extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *);
335#define XFS_BUF_SET_FSPRIVATE(bp, val) ((bp)->b_fspriv = (void*)(val)) 335#define XFS_BUF_SET_FSPRIVATE(bp, val) ((bp)->b_fspriv = (void*)(val))
336#define XFS_BUF_FSPRIVATE2(bp, type) ((type)(bp)->b_fspriv2) 336#define XFS_BUF_FSPRIVATE2(bp, type) ((type)(bp)->b_fspriv2)
337#define XFS_BUF_SET_FSPRIVATE2(bp, val) ((bp)->b_fspriv2 = (void*)(val)) 337#define XFS_BUF_SET_FSPRIVATE2(bp, val) ((bp)->b_fspriv2 = (void*)(val))
338#define XFS_BUF_FSPRIVATE3(bp, type) ((type)(bp)->b_fspriv3)
339#define XFS_BUF_SET_FSPRIVATE3(bp, val) ((bp)->b_fspriv3 = (void*)(val))
340#define XFS_BUF_SET_START(bp) do { } while (0) 338#define XFS_BUF_SET_START(bp) do { } while (0)
341#define XFS_BUF_SET_BRELSE_FUNC(bp, func) ((bp)->b_relse = (func)) 339#define XFS_BUF_SET_BRELSE_FUNC(bp, func) ((bp)->b_relse = (func))
342 340
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index f999d20a429c..a0c45cc8a6b8 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -45,81 +45,45 @@
45 45
46static struct vm_operations_struct xfs_file_vm_ops; 46static struct vm_operations_struct xfs_file_vm_ops;
47 47
48STATIC_INLINE ssize_t 48STATIC ssize_t
49__xfs_file_read( 49xfs_file_aio_read(
50 struct kiocb *iocb, 50 struct kiocb *iocb,
51 const struct iovec *iov, 51 const struct iovec *iov,
52 unsigned long nr_segs, 52 unsigned long nr_segs,
53 int ioflags,
54 loff_t pos) 53 loff_t pos)
55{ 54{
56 struct file *file = iocb->ki_filp; 55 struct file *file = iocb->ki_filp;
56 int ioflags = IO_ISAIO;
57 57
58 BUG_ON(iocb->ki_pos != pos); 58 BUG_ON(iocb->ki_pos != pos);
59 if (unlikely(file->f_flags & O_DIRECT)) 59 if (unlikely(file->f_flags & O_DIRECT))
60 ioflags |= IO_ISDIRECT; 60 ioflags |= IO_ISDIRECT;
61 if (file->f_mode & FMODE_NOCMTIME)
62 ioflags |= IO_INVIS;
61 return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov, 63 return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov,
62 nr_segs, &iocb->ki_pos, ioflags); 64 nr_segs, &iocb->ki_pos, ioflags);
63} 65}
64 66
65STATIC ssize_t 67STATIC ssize_t
66xfs_file_aio_read( 68xfs_file_aio_write(
67 struct kiocb *iocb,
68 const struct iovec *iov,
69 unsigned long nr_segs,
70 loff_t pos)
71{
72 return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO, pos);
73}
74
75STATIC ssize_t
76xfs_file_aio_read_invis(
77 struct kiocb *iocb,
78 const struct iovec *iov,
79 unsigned long nr_segs,
80 loff_t pos)
81{
82 return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
83}
84
85STATIC_INLINE ssize_t
86__xfs_file_write(
87 struct kiocb *iocb, 69 struct kiocb *iocb,
88 const struct iovec *iov, 70 const struct iovec *iov,
89 unsigned long nr_segs, 71 unsigned long nr_segs,
90 int ioflags,
91 loff_t pos) 72 loff_t pos)
92{ 73{
93 struct file *file = iocb->ki_filp; 74 struct file *file = iocb->ki_filp;
75 int ioflags = IO_ISAIO;
94 76
95 BUG_ON(iocb->ki_pos != pos); 77 BUG_ON(iocb->ki_pos != pos);
96 if (unlikely(file->f_flags & O_DIRECT)) 78 if (unlikely(file->f_flags & O_DIRECT))
97 ioflags |= IO_ISDIRECT; 79 ioflags |= IO_ISDIRECT;
80 if (file->f_mode & FMODE_NOCMTIME)
81 ioflags |= IO_INVIS;
98 return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs, 82 return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs,
99 &iocb->ki_pos, ioflags); 83 &iocb->ki_pos, ioflags);
100} 84}
101 85
102STATIC ssize_t 86STATIC ssize_t
103xfs_file_aio_write(
104 struct kiocb *iocb,
105 const struct iovec *iov,
106 unsigned long nr_segs,
107 loff_t pos)
108{
109 return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO, pos);
110}
111
112STATIC ssize_t
113xfs_file_aio_write_invis(
114 struct kiocb *iocb,
115 const struct iovec *iov,
116 unsigned long nr_segs,
117 loff_t pos)
118{
119 return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
120}
121
122STATIC ssize_t
123xfs_file_splice_read( 87xfs_file_splice_read(
124 struct file *infilp, 88 struct file *infilp,
125 loff_t *ppos, 89 loff_t *ppos,
@@ -127,20 +91,13 @@ xfs_file_splice_read(
127 size_t len, 91 size_t len,
128 unsigned int flags) 92 unsigned int flags)
129{ 93{
130 return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode), 94 int ioflags = 0;
131 infilp, ppos, pipe, len, flags, 0); 95
132} 96 if (infilp->f_mode & FMODE_NOCMTIME)
97 ioflags |= IO_INVIS;
133 98
134STATIC ssize_t
135xfs_file_splice_read_invis(
136 struct file *infilp,
137 loff_t *ppos,
138 struct pipe_inode_info *pipe,
139 size_t len,
140 unsigned int flags)
141{
142 return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode), 99 return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
143 infilp, ppos, pipe, len, flags, IO_INVIS); 100 infilp, ppos, pipe, len, flags, ioflags);
144} 101}
145 102
146STATIC ssize_t 103STATIC ssize_t
@@ -151,20 +108,13 @@ xfs_file_splice_write(
151 size_t len, 108 size_t len,
152 unsigned int flags) 109 unsigned int flags)
153{ 110{
154 return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode), 111 int ioflags = 0;
155 pipe, outfilp, ppos, len, flags, 0); 112
156} 113 if (outfilp->f_mode & FMODE_NOCMTIME)
114 ioflags |= IO_INVIS;
157 115
158STATIC ssize_t
159xfs_file_splice_write_invis(
160 struct pipe_inode_info *pipe,
161 struct file *outfilp,
162 loff_t *ppos,
163 size_t len,
164 unsigned int flags)
165{
166 return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode), 116 return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
167 pipe, outfilp, ppos, len, flags, IO_INVIS); 117 pipe, outfilp, ppos, len, flags, ioflags);
168} 118}
169 119
170STATIC int 120STATIC int
@@ -275,42 +225,6 @@ xfs_file_mmap(
275 return 0; 225 return 0;
276} 226}
277 227
278STATIC long
279xfs_file_ioctl(
280 struct file *filp,
281 unsigned int cmd,
282 unsigned long p)
283{
284 struct inode *inode = filp->f_path.dentry->d_inode;
285
286
287 /* NOTE: some of the ioctl's return positive #'s as a
288 * byte count indicating success, such as
289 * readlink_by_handle. So we don't "sign flip"
290 * like most other routines. This means true
291 * errors need to be returned as a negative value.
292 */
293 return xfs_ioctl(XFS_I(inode), filp, 0, cmd, (void __user *)p);
294}
295
296STATIC long
297xfs_file_ioctl_invis(
298 struct file *filp,
299 unsigned int cmd,
300 unsigned long p)
301{
302 struct inode *inode = filp->f_path.dentry->d_inode;
303
304
305 /* NOTE: some of the ioctl's return positive #'s as a
306 * byte count indicating success, such as
307 * readlink_by_handle. So we don't "sign flip"
308 * like most other routines. This means true
309 * errors need to be returned as a negative value.
310 */
311 return xfs_ioctl(XFS_I(inode), filp, IO_INVIS, cmd, (void __user *)p);
312}
313
314/* 228/*
315 * mmap()d file has taken write protection fault and is being made 229 * mmap()d file has taken write protection fault and is being made
316 * writable. We can set the page state up correctly for a writable 230 * writable. We can set the page state up correctly for a writable
@@ -346,25 +260,6 @@ const struct file_operations xfs_file_operations = {
346#endif 260#endif
347}; 261};
348 262
349const struct file_operations xfs_invis_file_operations = {
350 .llseek = generic_file_llseek,
351 .read = do_sync_read,
352 .write = do_sync_write,
353 .aio_read = xfs_file_aio_read_invis,
354 .aio_write = xfs_file_aio_write_invis,
355 .splice_read = xfs_file_splice_read_invis,
356 .splice_write = xfs_file_splice_write_invis,
357 .unlocked_ioctl = xfs_file_ioctl_invis,
358#ifdef CONFIG_COMPAT
359 .compat_ioctl = xfs_file_compat_invis_ioctl,
360#endif
361 .mmap = xfs_file_mmap,
362 .open = xfs_file_open,
363 .release = xfs_file_release,
364 .fsync = xfs_file_fsync,
365};
366
367
368const struct file_operations xfs_dir_file_operations = { 263const struct file_operations xfs_dir_file_operations = {
369 .open = xfs_dir_open, 264 .open = xfs_dir_open,
370 .read = generic_read_dir, 265 .read = generic_read_dir,
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index c8f1e632ba94..0264c8719ffd 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -319,10 +319,11 @@ xfs_open_by_handle(
319 put_unused_fd(new_fd); 319 put_unused_fd(new_fd);
320 return -XFS_ERROR(-PTR_ERR(filp)); 320 return -XFS_ERROR(-PTR_ERR(filp));
321 } 321 }
322
322 if (inode->i_mode & S_IFREG) { 323 if (inode->i_mode & S_IFREG) {
323 /* invisible operation should not change atime */ 324 /* invisible operation should not change atime */
324 filp->f_flags |= O_NOATIME; 325 filp->f_flags |= O_NOATIME;
325 filp->f_op = &xfs_invis_file_operations; 326 filp->f_mode |= FMODE_NOCMTIME;
326 } 327 }
327 328
328 fd_install(new_fd, filp); 329 fd_install(new_fd, filp);
@@ -1328,21 +1329,31 @@ xfs_ioc_getbmapx(
1328 return 0; 1329 return 0;
1329} 1330}
1330 1331
1331int 1332/*
1332xfs_ioctl( 1333 * Note: some of the ioctl's return positive numbers as a
1333 xfs_inode_t *ip, 1334 * byte count indicating success, such as readlink_by_handle.
1335 * So we don't "sign flip" like most other routines. This means
1336 * true errors need to be returned as a negative value.
1337 */
1338long
1339xfs_file_ioctl(
1334 struct file *filp, 1340 struct file *filp,
1335 int ioflags,
1336 unsigned int cmd, 1341 unsigned int cmd,
1337 void __user *arg) 1342 unsigned long p)
1338{ 1343{
1339 struct inode *inode = filp->f_path.dentry->d_inode; 1344 struct inode *inode = filp->f_path.dentry->d_inode;
1340 xfs_mount_t *mp = ip->i_mount; 1345 struct xfs_inode *ip = XFS_I(inode);
1346 struct xfs_mount *mp = ip->i_mount;
1347 void __user *arg = (void __user *)p;
1348 int ioflags = 0;
1341 int error; 1349 int error;
1342 1350
1343 xfs_itrace_entry(XFS_I(inode)); 1351 if (filp->f_mode & FMODE_NOCMTIME)
1344 switch (cmd) { 1352 ioflags |= IO_INVIS;
1345 1353
1354 xfs_itrace_entry(ip);
1355
1356 switch (cmd) {
1346 case XFS_IOC_ALLOCSP: 1357 case XFS_IOC_ALLOCSP:
1347 case XFS_IOC_FREESP: 1358 case XFS_IOC_FREESP:
1348 case XFS_IOC_RESVSP: 1359 case XFS_IOC_RESVSP:
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.h b/fs/xfs/linux-2.6/xfs_ioctl.h
index d92131c827bc..8c16bf2d7e03 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.h
+++ b/fs/xfs/linux-2.6/xfs_ioctl.h
@@ -68,13 +68,13 @@ xfs_attrmulti_attr_remove(
68 __uint32_t flags); 68 __uint32_t flags);
69 69
70extern long 70extern long
71xfs_file_compat_ioctl( 71xfs_file_ioctl(
72 struct file *file, 72 struct file *filp,
73 unsigned int cmd, 73 unsigned int cmd,
74 unsigned long arg); 74 unsigned long p);
75 75
76extern long 76extern long
77xfs_file_compat_invis_ioctl( 77xfs_file_compat_ioctl(
78 struct file *file, 78 struct file *file,
79 unsigned int cmd, 79 unsigned int cmd,
80 unsigned long arg); 80 unsigned long arg);
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index b34b3d8892a2..0504cece9f66 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -599,19 +599,24 @@ out:
599 return error; 599 return error;
600} 600}
601 601
602STATIC long 602long
603xfs_compat_ioctl( 603xfs_file_compat_ioctl(
604 xfs_inode_t *ip, 604 struct file *filp,
605 struct file *filp, 605 unsigned cmd,
606 int ioflags, 606 unsigned long p)
607 unsigned cmd,
608 void __user *arg)
609{ 607{
610 struct inode *inode = filp->f_path.dentry->d_inode; 608 struct inode *inode = filp->f_path.dentry->d_inode;
611 xfs_mount_t *mp = ip->i_mount; 609 struct xfs_inode *ip = XFS_I(inode);
612 int error; 610 struct xfs_mount *mp = ip->i_mount;
611 void __user *arg = (void __user *)p;
612 int ioflags = 0;
613 int error;
614
615 if (filp->f_mode & FMODE_NOCMTIME)
616 ioflags |= IO_INVIS;
617
618 xfs_itrace_entry(ip);
613 619
614 xfs_itrace_entry(XFS_I(inode));
615 switch (cmd) { 620 switch (cmd) {
616 /* No size or alignment issues on any arch */ 621 /* No size or alignment issues on any arch */
617 case XFS_IOC_DIOINFO: 622 case XFS_IOC_DIOINFO:
@@ -632,7 +637,7 @@ xfs_compat_ioctl(
632 case XFS_IOC_GOINGDOWN: 637 case XFS_IOC_GOINGDOWN:
633 case XFS_IOC_ERROR_INJECTION: 638 case XFS_IOC_ERROR_INJECTION:
634 case XFS_IOC_ERROR_CLEARALL: 639 case XFS_IOC_ERROR_CLEARALL:
635 return xfs_ioctl(ip, filp, ioflags, cmd, arg); 640 return xfs_file_ioctl(filp, cmd, p);
636#ifndef BROKEN_X86_ALIGNMENT 641#ifndef BROKEN_X86_ALIGNMENT
637 /* These are handled fine if no alignment issues */ 642 /* These are handled fine if no alignment issues */
638 case XFS_IOC_ALLOCSP: 643 case XFS_IOC_ALLOCSP:
@@ -646,7 +651,7 @@ xfs_compat_ioctl(
646 case XFS_IOC_FSGEOMETRY_V1: 651 case XFS_IOC_FSGEOMETRY_V1:
647 case XFS_IOC_FSGROWFSDATA: 652 case XFS_IOC_FSGROWFSDATA:
648 case XFS_IOC_FSGROWFSRT: 653 case XFS_IOC_FSGROWFSRT:
649 return xfs_ioctl(ip, filp, ioflags, cmd, arg); 654 return xfs_file_ioctl(filp, cmd, p);
650#else 655#else
651 case XFS_IOC_ALLOCSP_32: 656 case XFS_IOC_ALLOCSP_32:
652 case XFS_IOC_FREESP_32: 657 case XFS_IOC_FREESP_32:
@@ -687,7 +692,7 @@ xfs_compat_ioctl(
687 case XFS_IOC_SETXFLAGS_32: 692 case XFS_IOC_SETXFLAGS_32:
688 case XFS_IOC_GETVERSION_32: 693 case XFS_IOC_GETVERSION_32:
689 cmd = _NATIVE_IOC(cmd, long); 694 cmd = _NATIVE_IOC(cmd, long);
690 return xfs_ioctl(ip, filp, ioflags, cmd, arg); 695 return xfs_file_ioctl(filp, cmd, p);
691 case XFS_IOC_SWAPEXT: { 696 case XFS_IOC_SWAPEXT: {
692 struct xfs_swapext sxp; 697 struct xfs_swapext sxp;
693 struct compat_xfs_swapext __user *sxu = arg; 698 struct compat_xfs_swapext __user *sxu = arg;
@@ -738,26 +743,3 @@ xfs_compat_ioctl(
738 return -XFS_ERROR(ENOIOCTLCMD); 743 return -XFS_ERROR(ENOIOCTLCMD);
739 } 744 }
740} 745}
741
742long
743xfs_file_compat_ioctl(
744 struct file *filp,
745 unsigned int cmd,
746 unsigned long p)
747{
748 struct inode *inode = filp->f_path.dentry->d_inode;
749
750 return xfs_compat_ioctl(XFS_I(inode), filp, 0, cmd, (void __user *)p);
751}
752
753long
754xfs_file_compat_invis_ioctl(
755 struct file *filp,
756 unsigned int cmd,
757 unsigned long p)
758{
759 struct inode *inode = filp->f_path.dentry->d_inode;
760
761 return xfs_compat_ioctl(XFS_I(inode), filp, IO_INVIS, cmd,
762 (void __user *)p);
763}
diff --git a/fs/xfs/linux-2.6/xfs_iops.h b/fs/xfs/linux-2.6/xfs_iops.h
index 8b1a1e31dc21..ef41c92ce66e 100644
--- a/fs/xfs/linux-2.6/xfs_iops.h
+++ b/fs/xfs/linux-2.6/xfs_iops.h
@@ -22,7 +22,6 @@ struct xfs_inode;
22 22
23extern const struct file_operations xfs_file_operations; 23extern const struct file_operations xfs_file_operations;
24extern const struct file_operations xfs_dir_file_operations; 24extern const struct file_operations xfs_dir_file_operations;
25extern const struct file_operations xfs_invis_file_operations;
26 25
27extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size); 26extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size);
28 27
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 59b7d5f9e64a..92ce34b3787a 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -847,13 +847,7 @@ retry:
847int 847int
848xfs_bdstrat_cb(struct xfs_buf *bp) 848xfs_bdstrat_cb(struct xfs_buf *bp)
849{ 849{
850 xfs_mount_t *mp; 850 if (XFS_FORCED_SHUTDOWN(bp->b_mount)) {
851
852 mp = XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *);
853 if (!XFS_FORCED_SHUTDOWN(mp)) {
854 xfs_buf_iorequest(bp);
855 return 0;
856 } else {
857 xfs_buftrace("XFS__BDSTRAT IOERROR", bp); 851 xfs_buftrace("XFS__BDSTRAT IOERROR", bp);
858 /* 852 /*
859 * Metadata write that didn't get logged but 853 * Metadata write that didn't get logged but
@@ -866,6 +860,9 @@ xfs_bdstrat_cb(struct xfs_buf *bp)
866 else 860 else
867 return (xfs_bioerror(bp)); 861 return (xfs_bioerror(bp));
868 } 862 }
863
864 xfs_buf_iorequest(bp);
865 return 0;
869} 866}
870 867
871/* 868/*
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index d245d04e10ca..d74ce1134262 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -707,8 +707,8 @@ xfs_buf_item_init(
707 * the first. If we do already have one, there is 707 * the first. If we do already have one, there is
708 * nothing to do here so return. 708 * nothing to do here so return.
709 */ 709 */
710 if (XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *) != mp) 710 if (bp->b_mount != mp)
711 XFS_BUF_SET_FSPRIVATE3(bp, mp); 711 bp->b_mount = mp;
712 XFS_BUF_SET_BDSTRAT_FUNC(bp, xfs_bdstrat_cb); 712 XFS_BUF_SET_BDSTRAT_FUNC(bp, xfs_bdstrat_cb);
713 if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) { 713 if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) {
714 lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); 714 lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 063da344e185..3adb868df183 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -870,7 +870,7 @@ xfs_iread(
870 * around for a while. This helps to keep recently accessed 870 * around for a while. This helps to keep recently accessed
871 * meta-data in-core longer. 871 * meta-data in-core longer.
872 */ 872 */
873 XFS_BUF_SET_REF(bp, XFS_INO_REF); 873 XFS_BUF_SET_REF(bp, XFS_INO_REF);
874 874
875 /* 875 /*
876 * Use xfs_trans_brelse() to release the buffer containing the 876 * Use xfs_trans_brelse() to release the buffer containing the
@@ -3232,8 +3232,6 @@ corrupt_out:
3232 3232
3233 3233
3234#ifdef XFS_ILOCK_TRACE 3234#ifdef XFS_ILOCK_TRACE
3235ktrace_t *xfs_ilock_trace_buf;
3236
3237void 3235void
3238xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra) 3236xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra)
3239{ 3237{
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 558253e6fb43..f0e4d79833e1 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -223,7 +223,6 @@ struct xfs_dquot;
223 223
224#if defined(XFS_ILOCK_TRACE) 224#if defined(XFS_ILOCK_TRACE)
225#define XFS_ILOCK_KTRACE_SIZE 32 225#define XFS_ILOCK_KTRACE_SIZE 32
226extern ktrace_t *xfs_ilock_trace_buf;
227extern void xfs_ilock_trace(struct xfs_inode *, int, unsigned int, inst_t *); 226extern void xfs_ilock_trace(struct xfs_inode *, int, unsigned int, inst_t *);
228#else 227#else
229#define xfs_ilock_trace(i,n,f,ra) 228#define xfs_ilock_trace(i,n,f,ra)
@@ -483,12 +482,6 @@ static inline void xfs_ifunlock(xfs_inode_t *ip)
483 ((pip)->i_d.di_mode & S_ISGID)) 482 ((pip)->i_d.di_mode & S_ISGID))
484 483
485/* 484/*
486 * Flags for xfs_iget()
487 */
488#define XFS_IGET_CREATE 0x1
489#define XFS_IGET_BULKSTAT 0x2
490
491/*
492 * xfs_iget.c prototypes. 485 * xfs_iget.c prototypes.
493 */ 486 */
494xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, 487xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
@@ -509,8 +502,6 @@ void xfs_ireclaim(xfs_inode_t *);
509/* 502/*
510 * xfs_inode.c prototypes. 503 * xfs_inode.c prototypes.
511 */ 504 */
512int xfs_iread(struct xfs_mount *, struct xfs_trans *,
513 struct xfs_inode *, xfs_daddr_t, uint);
514int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, 505int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
515 xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, 506 xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
516 int, struct xfs_buf **, boolean_t *, xfs_inode_t **); 507 int, struct xfs_buf **, boolean_t *, xfs_inode_t **);
@@ -583,12 +574,20 @@ do { \
583 574
584#endif /* __KERNEL__ */ 575#endif /* __KERNEL__ */
585 576
577/*
578 * Flags for xfs_iget()
579 */
580#define XFS_IGET_CREATE 0x1
581#define XFS_IGET_BULKSTAT 0x2
582
586int xfs_inotobp(struct xfs_mount *, struct xfs_trans *, 583int xfs_inotobp(struct xfs_mount *, struct xfs_trans *,
587 xfs_ino_t, struct xfs_dinode **, 584 xfs_ino_t, struct xfs_dinode **,
588 struct xfs_buf **, int *, uint); 585 struct xfs_buf **, int *, uint);
589int xfs_itobp(struct xfs_mount *, struct xfs_trans *, 586int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
590 struct xfs_inode *, struct xfs_dinode **, 587 struct xfs_inode *, struct xfs_dinode **,
591 struct xfs_buf **, uint); 588 struct xfs_buf **, uint);
589int xfs_iread(struct xfs_mount *, struct xfs_trans *,
590 struct xfs_inode *, xfs_daddr_t, uint);
592void xfs_dinode_from_disk(struct xfs_icdinode *, 591void xfs_dinode_from_disk(struct xfs_icdinode *,
593 struct xfs_dinode *); 592 struct xfs_dinode *);
594void xfs_dinode_to_disk(struct xfs_dinode *, 593void xfs_dinode_to_disk(struct xfs_dinode *,
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 51412cced010..35cca98bd94c 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -267,21 +267,16 @@ STATIC void
267xlog_recover_iodone( 267xlog_recover_iodone(
268 struct xfs_buf *bp) 268 struct xfs_buf *bp)
269{ 269{
270 xfs_mount_t *mp;
271
272 ASSERT(XFS_BUF_FSPRIVATE(bp, void *));
273
274 if (XFS_BUF_GETERROR(bp)) { 270 if (XFS_BUF_GETERROR(bp)) {
275 /* 271 /*
276 * We're not going to bother about retrying 272 * We're not going to bother about retrying
277 * this during recovery. One strike! 273 * this during recovery. One strike!
278 */ 274 */
279 mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *);
280 xfs_ioerror_alert("xlog_recover_iodone", 275 xfs_ioerror_alert("xlog_recover_iodone",
281 mp, bp, XFS_BUF_ADDR(bp)); 276 bp->b_mount, bp, XFS_BUF_ADDR(bp));
282 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); 277 xfs_force_shutdown(bp->b_mount, SHUTDOWN_META_IO_ERROR);
283 } 278 }
284 XFS_BUF_SET_FSPRIVATE(bp, NULL); 279 bp->b_mount = NULL;
285 XFS_BUF_CLR_IODONE_FUNC(bp); 280 XFS_BUF_CLR_IODONE_FUNC(bp);
286 xfs_biodone(bp); 281 xfs_biodone(bp);
287} 282}
@@ -2225,9 +2220,8 @@ xlog_recover_do_buffer_trans(
2225 XFS_BUF_STALE(bp); 2220 XFS_BUF_STALE(bp);
2226 error = xfs_bwrite(mp, bp); 2221 error = xfs_bwrite(mp, bp);
2227 } else { 2222 } else {
2228 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL || 2223 ASSERT(bp->b_mount == NULL || bp->b_mount == mp);
2229 XFS_BUF_FSPRIVATE(bp, xfs_mount_t *) == mp); 2224 bp->b_mount = mp;
2230 XFS_BUF_SET_FSPRIVATE(bp, mp);
2231 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone); 2225 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
2232 xfs_bdwrite(mp, bp); 2226 xfs_bdwrite(mp, bp);
2233 } 2227 }
@@ -2490,9 +2484,8 @@ xlog_recover_do_inode_trans(
2490 2484
2491write_inode_buffer: 2485write_inode_buffer:
2492 if (ITEM_TYPE(item) == XFS_LI_INODE) { 2486 if (ITEM_TYPE(item) == XFS_LI_INODE) {
2493 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL || 2487 ASSERT(bp->b_mount == NULL || bp->b_mount == mp);
2494 XFS_BUF_FSPRIVATE(bp, xfs_mount_t *) == mp); 2488 bp->b_mount = mp;
2495 XFS_BUF_SET_FSPRIVATE(bp, mp);
2496 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone); 2489 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
2497 xfs_bdwrite(mp, bp); 2490 xfs_bdwrite(mp, bp);
2498 } else { 2491 } else {
@@ -2623,9 +2616,8 @@ xlog_recover_do_dquot_trans(
2623 memcpy(ddq, recddq, item->ri_buf[1].i_len); 2616 memcpy(ddq, recddq, item->ri_buf[1].i_len);
2624 2617
2625 ASSERT(dq_f->qlf_size == 2); 2618 ASSERT(dq_f->qlf_size == 2);
2626 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL || 2619 ASSERT(bp->b_mount == NULL || bp->b_mount == mp);
2627 XFS_BUF_FSPRIVATE(bp, xfs_mount_t *) == mp); 2620 bp->b_mount = mp;
2628 XFS_BUF_SET_FSPRIVATE(bp, mp);
2629 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone); 2621 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
2630 xfs_bdwrite(mp, bp); 2622 xfs_bdwrite(mp, bp);
2631 2623
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index ae5da88ace20..c1e028467327 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -18,8 +18,6 @@
18#ifndef __XFS_MOUNT_H__ 18#ifndef __XFS_MOUNT_H__
19#define __XFS_MOUNT_H__ 19#define __XFS_MOUNT_H__
20 20
21#include "xfs_sync.h"
22
23typedef struct xfs_trans_reservations { 21typedef struct xfs_trans_reservations {
24 uint tr_write; /* extent alloc trans */ 22 uint tr_write; /* extent alloc trans */
25 uint tr_itruncate; /* truncate trans */ 23 uint tr_itruncate; /* truncate trans */
@@ -53,6 +51,8 @@ typedef struct xfs_trans_reservations {
53 51
54#else /* __KERNEL__ */ 52#else /* __KERNEL__ */
55 53
54#include "xfs_sync.h"
55
56struct cred; 56struct cred;
57struct log; 57struct log;
58struct xfs_mount_args; 58struct xfs_mount_args;
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 10642fcbb1f7..86471bb40fd4 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -42,31 +42,6 @@
42 42
43 43
44/* 44/*
45 * Given an array of up to 4 inode pointers, unlock the pointed to inodes.
46 * If there are fewer than 4 entries in the array, the empty entries will
47 * be at the end and will have NULL pointers in them.
48 */
49STATIC void
50xfs_rename_unlock4(
51 xfs_inode_t **i_tab,
52 uint lock_mode)
53{
54 int i;
55
56 xfs_iunlock(i_tab[0], lock_mode);
57 for (i = 1; i < 4; i++) {
58 if (i_tab[i] == NULL)
59 break;
60
61 /*
62 * Watch out for duplicate entries in the table.
63 */
64 if (i_tab[i] != i_tab[i-1])
65 xfs_iunlock(i_tab[i], lock_mode);
66 }
67}
68
69/*
70 * Enter all inodes for a rename transaction into a sorted array. 45 * Enter all inodes for a rename transaction into a sorted array.
71 */ 46 */
72STATIC void 47STATIC void
@@ -205,19 +180,6 @@ xfs_rename(
205 xfs_lock_inodes(inodes, num_inodes, XFS_ILOCK_EXCL); 180 xfs_lock_inodes(inodes, num_inodes, XFS_ILOCK_EXCL);
206 181
207 /* 182 /*
208 * If we are using project inheritance, we only allow renames
209 * into our tree when the project IDs are the same; else the
210 * tree quota mechanism would be circumvented.
211 */
212 if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
213 (target_dp->i_d.di_projid != src_ip->i_d.di_projid))) {
214 error = XFS_ERROR(EXDEV);
215 xfs_rename_unlock4(inodes, XFS_ILOCK_EXCL);
216 xfs_trans_cancel(tp, cancel_flags);
217 goto std_return;
218 }
219
220 /*
221 * Join all the inodes to the transaction. From this point on, 183 * Join all the inodes to the transaction. From this point on,
222 * we can rely on either trans_commit or trans_cancel to unlock 184 * we can rely on either trans_commit or trans_cancel to unlock
223 * them. Note that we need to add a vnode reference to the 185 * them. Note that we need to add a vnode reference to the
@@ -242,6 +204,17 @@ xfs_rename(
242 } 204 }
243 205
244 /* 206 /*
207 * If we are using project inheritance, we only allow renames
208 * into our tree when the project IDs are the same; else the
209 * tree quota mechanism would be circumvented.
210 */
211 if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
212 (target_dp->i_d.di_projid != src_ip->i_d.di_projid))) {
213 error = XFS_ERROR(EXDEV);
214 goto error_return;
215 }
216
217 /*
245 * Set up the target. 218 * Set up the target.
246 */ 219 */
247 if (target_ip == NULL) { 220 if (target_ip == NULL) {
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index 3a82576dde9a..36f3a21c54d2 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -406,7 +406,7 @@ xfs_bwrite(
406 * XXXsup how does this work for quotas. 406 * XXXsup how does this work for quotas.
407 */ 407 */
408 XFS_BUF_SET_BDSTRAT_FUNC(bp, xfs_bdstrat_cb); 408 XFS_BUF_SET_BDSTRAT_FUNC(bp, xfs_bdstrat_cb);
409 XFS_BUF_SET_FSPRIVATE3(bp, mp); 409 bp->b_mount = mp;
410 XFS_BUF_WRITE(bp); 410 XFS_BUF_WRITE(bp);
411 411
412 if ((error = XFS_bwrite(bp))) { 412 if ((error = XFS_bwrite(bp))) {
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index e123c1499b4c..1ed71916e4c9 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -79,6 +79,7 @@ struct xfs_mount;
79#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */ 79#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */
80#define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 80#define XFS_SB_VERSION2_RESERVED4BIT 0x00000004
81#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ 81#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */
82#define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */
82 83
83#define XFS_SB_VERSION2_OKREALFBITS \ 84#define XFS_SB_VERSION2_OKREALFBITS \
84 (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ 85 (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 4547608b46c4..f07bf8768c3a 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -70,7 +70,6 @@ xfs_setattr(
70 gid_t gid=0, igid=0; 70 gid_t gid=0, igid=0;
71 int timeflags = 0; 71 int timeflags = 0;
72 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; 72 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
73 int file_owner;
74 int need_iolock = 1; 73 int need_iolock = 1;
75 74
76 xfs_itrace_entry(ip); 75 xfs_itrace_entry(ip);
@@ -81,6 +80,10 @@ xfs_setattr(
81 if (XFS_FORCED_SHUTDOWN(mp)) 80 if (XFS_FORCED_SHUTDOWN(mp))
82 return XFS_ERROR(EIO); 81 return XFS_ERROR(EIO);
83 82
83 code = -inode_change_ok(inode, iattr);
84 if (code)
85 return code;
86
84 olddquot1 = olddquot2 = NULL; 87 olddquot1 = olddquot2 = NULL;
85 udqp = gdqp = NULL; 88 udqp = gdqp = NULL;
86 89
@@ -158,56 +161,6 @@ xfs_setattr(
158 161
159 xfs_ilock(ip, lock_flags); 162 xfs_ilock(ip, lock_flags);
160 163
161 /* boolean: are we the file owner? */
162 file_owner = (current_fsuid() == ip->i_d.di_uid);
163
164 /*
165 * Change various properties of a file.
166 * Only the owner or users with CAP_FOWNER
167 * capability may do these things.
168 */
169 if (mask & (ATTR_MODE|ATTR_UID|ATTR_GID)) {
170 /*
171 * CAP_FOWNER overrides the following restrictions:
172 *
173 * The user ID of the calling process must be equal
174 * to the file owner ID, except in cases where the
175 * CAP_FSETID capability is applicable.
176 */
177 if (!file_owner && !capable(CAP_FOWNER)) {
178 code = XFS_ERROR(EPERM);
179 goto error_return;
180 }
181
182 /*
183 * CAP_FSETID overrides the following restrictions:
184 *
185 * The effective user ID of the calling process shall match
186 * the file owner when setting the set-user-ID and
187 * set-group-ID bits on that file.
188 *
189 * The effective group ID or one of the supplementary group
190 * IDs of the calling process shall match the group owner of
191 * the file when setting the set-group-ID bit on that file
192 */
193 if (mask & ATTR_MODE) {
194 mode_t m = 0;
195
196 if ((iattr->ia_mode & S_ISUID) && !file_owner)
197 m |= S_ISUID;
198 if ((iattr->ia_mode & S_ISGID) &&
199 !in_group_p((gid_t)ip->i_d.di_gid))
200 m |= S_ISGID;
201#if 0
202 /* Linux allows this, Irix doesn't. */
203 if ((iattr->ia_mode & S_ISVTX) && !S_ISDIR(ip->i_d.di_mode))
204 m |= S_ISVTX;
205#endif
206 if (m && !capable(CAP_FSETID))
207 iattr->ia_mode &= ~m;
208 }
209 }
210
211 /* 164 /*
212 * Change file ownership. Must be the owner or privileged. 165 * Change file ownership. Must be the owner or privileged.
213 */ 166 */
@@ -224,22 +177,6 @@ xfs_setattr(
224 uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid; 177 uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid;
225 178
226 /* 179 /*
227 * CAP_CHOWN overrides the following restrictions:
228 *
229 * If _POSIX_CHOWN_RESTRICTED is defined, this capability
230 * shall override the restriction that a process cannot
231 * change the user ID of a file it owns and the restriction
232 * that the group ID supplied to the chown() function
233 * shall be equal to either the group ID or one of the
234 * supplementary group IDs of the calling process.
235 */
236 if ((iuid != uid ||
237 (igid != gid && !in_group_p((gid_t)gid))) &&
238 !capable(CAP_CHOWN)) {
239 code = XFS_ERROR(EPERM);
240 goto error_return;
241 }
242 /*
243 * Do a quota reservation only if uid/gid is actually 180 * Do a quota reservation only if uid/gid is actually
244 * going to change. 181 * going to change.
245 */ 182 */
@@ -276,36 +213,22 @@ xfs_setattr(
276 code = XFS_ERROR(EINVAL); 213 code = XFS_ERROR(EINVAL);
277 goto error_return; 214 goto error_return;
278 } 215 }
216
279 /* 217 /*
280 * Make sure that the dquots are attached to the inode. 218 * Make sure that the dquots are attached to the inode.
281 */ 219 */
282 if ((code = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED))) 220 code = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED);
221 if (code)
283 goto error_return; 222 goto error_return;
284 }
285 223
286 /* 224 /*
287 * Change file access or modified times. 225 * Now we can make the changes. Before we join the inode
288 */ 226 * to the transaction, if ATTR_SIZE is set then take care of
289 if (mask & (ATTR_ATIME|ATTR_MTIME)) { 227 * the part of the truncation that must be done without the
290 if (!file_owner) { 228 * inode lock. This needs to be done before joining the inode
291 if ((mask & (ATTR_MTIME_SET|ATTR_ATIME_SET)) && 229 * to the transaction, because the inode cannot be unlocked
292 !capable(CAP_FOWNER)) { 230 * once it is a part of the transaction.
293 code = XFS_ERROR(EPERM); 231 */
294 goto error_return;
295 }
296 }
297 }
298
299 /*
300 * Now we can make the changes. Before we join the inode
301 * to the transaction, if ATTR_SIZE is set then take care of
302 * the part of the truncation that must be done without the
303 * inode lock. This needs to be done before joining the inode
304 * to the transaction, because the inode cannot be unlocked
305 * once it is a part of the transaction.
306 */
307 if (mask & ATTR_SIZE) {
308 code = 0;
309 if (iattr->ia_size > ip->i_size) { 232 if (iattr->ia_size > ip->i_size) {
310 /* 233 /*
311 * Do the first part of growing a file: zero any data 234 * Do the first part of growing a file: zero any data
@@ -360,17 +283,10 @@ xfs_setattr(
360 } 283 }
361 commit_flags = XFS_TRANS_RELEASE_LOG_RES; 284 commit_flags = XFS_TRANS_RELEASE_LOG_RES;
362 xfs_ilock(ip, XFS_ILOCK_EXCL); 285 xfs_ilock(ip, XFS_ILOCK_EXCL);
363 }
364 286
365 if (tp) {
366 xfs_trans_ijoin(tp, ip, lock_flags); 287 xfs_trans_ijoin(tp, ip, lock_flags);
367 xfs_trans_ihold(tp, ip); 288 xfs_trans_ihold(tp, ip);
368 }
369 289
370 /*
371 * Truncate file. Must have write permission and not be a directory.
372 */
373 if (mask & ATTR_SIZE) {
374 /* 290 /*
375 * Only change the c/mtime if we are changing the size 291 * Only change the c/mtime if we are changing the size
376 * or we are explicitly asked to change it. This handles 292 * or we are explicitly asked to change it. This handles
@@ -410,20 +326,9 @@ xfs_setattr(
410 */ 326 */
411 xfs_iflags_set(ip, XFS_ITRUNCATED); 327 xfs_iflags_set(ip, XFS_ITRUNCATED);
412 } 328 }
413 } 329 } else if (tp) {
414 330 xfs_trans_ijoin(tp, ip, lock_flags);
415 /* 331 xfs_trans_ihold(tp, ip);
416 * Change file access modes.
417 */
418 if (mask & ATTR_MODE) {
419 ip->i_d.di_mode &= S_IFMT;
420 ip->i_d.di_mode |= iattr->ia_mode & ~S_IFMT;
421
422 inode->i_mode &= S_IFMT;
423 inode->i_mode |= iattr->ia_mode & ~S_IFMT;
424
425 xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE);
426 timeflags |= XFS_ICHGTIME_CHG;
427 } 332 }
428 333
429 /* 334 /*
@@ -471,6 +376,24 @@ xfs_setattr(
471 timeflags |= XFS_ICHGTIME_CHG; 376 timeflags |= XFS_ICHGTIME_CHG;
472 } 377 }
473 378
379 /*
380 * Change file access modes.
381 */
382 if (mask & ATTR_MODE) {
383 umode_t mode = iattr->ia_mode;
384
385 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
386 mode &= ~S_ISGID;
387
388 ip->i_d.di_mode &= S_IFMT;
389 ip->i_d.di_mode |= mode & ~S_IFMT;
390
391 inode->i_mode &= S_IFMT;
392 inode->i_mode |= mode & ~S_IFMT;
393
394 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
395 timeflags |= XFS_ICHGTIME_CHG;
396 }
474 397
475 /* 398 /*
476 * Change file access or modified times. 399 * Change file access or modified times.
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index 2a45b00ad32e..55d955ec4ece 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -53,8 +53,6 @@ int xfs_attr_set(struct xfs_inode *dp, const char *name, char *value,
53int xfs_attr_remove(struct xfs_inode *dp, const char *name, int flags); 53int xfs_attr_remove(struct xfs_inode *dp, const char *name, int flags);
54int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, 54int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
55 int flags, struct attrlist_cursor_kern *cursor); 55 int flags, struct attrlist_cursor_kern *cursor);
56int xfs_ioctl(struct xfs_inode *ip, struct file *filp,
57 int ioflags, unsigned int cmd, void __user *arg);
58ssize_t xfs_read(struct xfs_inode *ip, struct kiocb *iocb, 56ssize_t xfs_read(struct xfs_inode *ip, struct kiocb *iocb,
59 const struct iovec *iovp, unsigned int segs, 57 const struct iovec *iovp, unsigned int segs,
60 loff_t *offset, int ioflags); 58 loff_t *offset, int ioflags);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 51bd9370d437..965b9ba3865d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -81,6 +81,14 @@ extern int dir_notify_enable;
81#define FMODE_WRITE_IOCTL ((__force fmode_t)128) 81#define FMODE_WRITE_IOCTL ((__force fmode_t)128)
82#define FMODE_NDELAY_NOW ((__force fmode_t)256) 82#define FMODE_NDELAY_NOW ((__force fmode_t)256)
83 83
84/*
85 * Don't update ctime and mtime.
86 *
87 * Currently a special hack for the XFS open_by_handle ioctl, but we'll
88 * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon.
89 */
90#define FMODE_NOCMTIME ((__force fmode_t)2048)
91
84#define RW_MASK 1 92#define RW_MASK 1
85#define RWA_MASK 2 93#define RWA_MASK 2
86#define READ 0 94#define READ 0