aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_iops.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-01-12 12:10:34 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-12 12:10:34 -0500
commit9f5974c8734d83d4ab7096ed98136a82f41210d6 (patch)
tree6f328555796bafefb74936ab68128aa84efd28b1 /fs/xfs/linux-2.6/xfs_iops.c
parenta2d823bf13efea4c859376f6e85c49cfbad7ab60 (diff)
parentddae9c2ea79449beb00027cf77fca6dc489f2d15 (diff)
Merge git://oss.sgi.com:8090/oss/git/xfs-2.6
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_iops.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c121
1 files changed, 81 insertions, 40 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 9b8ee3470ecc..4bd3d03b23ed 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -54,11 +54,46 @@
54#include <linux/capability.h> 54#include <linux/capability.h>
55#include <linux/xattr.h> 55#include <linux/xattr.h>
56#include <linux/namei.h> 56#include <linux/namei.h>
57#include <linux/security.h>
57 58
58#define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) || \ 59#define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) || \
59 (S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME)) 60 (S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME))
60 61
61/* 62/*
63 * Get a XFS inode from a given vnode.
64 */
65xfs_inode_t *
66xfs_vtoi(
67 struct vnode *vp)
68{
69 bhv_desc_t *bdp;
70
71 bdp = bhv_lookup_range(VN_BHV_HEAD(vp),
72 VNODE_POSITION_XFS, VNODE_POSITION_XFS);
73 if (unlikely(bdp == NULL))
74 return NULL;
75 return XFS_BHVTOI(bdp);
76}
77
78/*
79 * Bring the atime in the XFS inode uptodate.
80 * Used before logging the inode to disk or when the Linux inode goes away.
81 */
82void
83xfs_synchronize_atime(
84 xfs_inode_t *ip)
85{
86 vnode_t *vp;
87
88 vp = XFS_ITOV_NULL(ip);
89 if (vp) {
90 struct inode *inode = &vp->v_inode;
91 ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
92 ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
93 }
94}
95
96/*
62 * Change the requested timestamp in the given inode. 97 * Change the requested timestamp in the given inode.
63 * We don't lock across timestamp updates, and we don't log them but 98 * We don't lock across timestamp updates, and we don't log them but
64 * we do record the fact that there is dirty information in core. 99 * we do record the fact that there is dirty information in core.
@@ -77,23 +112,6 @@ xfs_ichgtime(
77 struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip)); 112 struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));
78 timespec_t tv; 113 timespec_t tv;
79 114
80 /*
81 * We're not supposed to change timestamps in readonly-mounted
82 * filesystems. Throw it away if anyone asks us.
83 */
84 if (unlikely(IS_RDONLY(inode)))
85 return;
86
87 /*
88 * Don't update access timestamps on reads if mounted "noatime".
89 * Throw it away if anyone asks us.
90 */
91 if (unlikely(
92 (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
93 (flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
94 XFS_ICHGTIME_ACC))
95 return;
96
97 nanotime(&tv); 115 nanotime(&tv);
98 if (flags & XFS_ICHGTIME_MOD) { 116 if (flags & XFS_ICHGTIME_MOD) {
99 inode->i_mtime = tv; 117 inode->i_mtime = tv;
@@ -130,8 +148,6 @@ xfs_ichgtime(
130 * Variant on the above which avoids querying the system clock 148 * Variant on the above which avoids querying the system clock
131 * in situations where we know the Linux inode timestamps have 149 * in situations where we know the Linux inode timestamps have
132 * just been updated (and so we can update our inode cheaply). 150 * just been updated (and so we can update our inode cheaply).
133 * We also skip the readonly and noatime checks here, they are
134 * also catered for already.
135 */ 151 */
136void 152void
137xfs_ichgtime_fast( 153xfs_ichgtime_fast(
@@ -142,20 +158,16 @@ xfs_ichgtime_fast(
142 timespec_t *tvp; 158 timespec_t *tvp;
143 159
144 /* 160 /*
145 * We're not supposed to change timestamps in readonly-mounted 161 * Atime updates for read() & friends are handled lazily now, and
146 * filesystems. Throw it away if anyone asks us. 162 * explicit updates must go through xfs_ichgtime()
147 */ 163 */
148 if (unlikely(IS_RDONLY(inode))) 164 ASSERT((flags & XFS_ICHGTIME_ACC) == 0);
149 return;
150 165
151 /* 166 /*
152 * Don't update access timestamps on reads if mounted "noatime". 167 * We're not supposed to change timestamps in readonly-mounted
153 * Throw it away if anyone asks us. 168 * filesystems. Throw it away if anyone asks us.
154 */ 169 */
155 if (unlikely( 170 if (unlikely(IS_RDONLY(inode)))
156 (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
157 ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
158 XFS_ICHGTIME_ACC)))
159 return; 171 return;
160 172
161 if (flags & XFS_ICHGTIME_MOD) { 173 if (flags & XFS_ICHGTIME_MOD) {
@@ -163,11 +175,6 @@ xfs_ichgtime_fast(
163 ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec; 175 ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec;
164 ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec; 176 ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec;
165 } 177 }
166 if (flags & XFS_ICHGTIME_ACC) {
167 tvp = &inode->i_atime;
168 ip->i_d.di_atime.t_sec = (__int32_t)tvp->tv_sec;
169 ip->i_d.di_atime.t_nsec = (__int32_t)tvp->tv_nsec;
170 }
171 if (flags & XFS_ICHGTIME_CHG) { 178 if (flags & XFS_ICHGTIME_CHG) {
172 tvp = &inode->i_ctime; 179 tvp = &inode->i_ctime;
173 ip->i_d.di_ctime.t_sec = (__int32_t)tvp->tv_sec; 180 ip->i_d.di_ctime.t_sec = (__int32_t)tvp->tv_sec;
@@ -214,6 +221,39 @@ validate_fields(
214} 221}
215 222
216/* 223/*
224 * Hook in SELinux. This is not quite correct yet, what we really need
225 * here (as we do for default ACLs) is a mechanism by which creation of
226 * these attrs can be journalled at inode creation time (along with the
227 * inode, of course, such that log replay can't cause these to be lost).
228 */
229STATIC int
230linvfs_init_security(
231 struct vnode *vp,
232 struct inode *dir)
233{
234 struct inode *ip = LINVFS_GET_IP(vp);
235 size_t length;
236 void *value;
237 char *name;
238 int error;
239
240 error = security_inode_init_security(ip, dir, &name, &value, &length);
241 if (error) {
242 if (error == -EOPNOTSUPP)
243 return 0;
244 return -error;
245 }
246
247 VOP_ATTR_SET(vp, name, value, length, ATTR_SECURE, NULL, error);
248 if (!error)
249 VMODIFY(vp);
250
251 kfree(name);
252 kfree(value);
253 return error;
254}
255
256/*
217 * Determine whether a process has a valid fs_struct (kernel daemons 257 * Determine whether a process has a valid fs_struct (kernel daemons
218 * like knfsd don't have an fs_struct). 258 * like knfsd don't have an fs_struct).
219 * 259 *
@@ -278,6 +318,9 @@ linvfs_mknod(
278 break; 318 break;
279 } 319 }
280 320
321 if (!error)
322 error = linvfs_init_security(vp, dir);
323
281 if (default_acl) { 324 if (default_acl) {
282 if (!error) { 325 if (!error) {
283 error = _ACL_INHERIT(vp, &va, default_acl); 326 error = _ACL_INHERIT(vp, &va, default_acl);
@@ -294,8 +337,6 @@ linvfs_mknod(
294 teardown.d_inode = ip = LINVFS_GET_IP(vp); 337 teardown.d_inode = ip = LINVFS_GET_IP(vp);
295 teardown.d_name = dentry->d_name; 338 teardown.d_name = dentry->d_name;
296 339
297 vn_mark_bad(vp);
298
299 if (S_ISDIR(mode)) 340 if (S_ISDIR(mode))
300 VOP_RMDIR(dvp, &teardown, NULL, err2); 341 VOP_RMDIR(dvp, &teardown, NULL, err2);
301 else 342 else
@@ -506,7 +547,7 @@ linvfs_follow_link(
506 ASSERT(dentry); 547 ASSERT(dentry);
507 ASSERT(nd); 548 ASSERT(nd);
508 549
509 link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL); 550 link = (char *)kmalloc(MAXPATHLEN+1, GFP_KERNEL);
510 if (!link) { 551 if (!link) {
511 nd_set_link(nd, ERR_PTR(-ENOMEM)); 552 nd_set_link(nd, ERR_PTR(-ENOMEM));
512 return NULL; 553 return NULL;
@@ -522,12 +563,12 @@ linvfs_follow_link(
522 vp = LINVFS_GET_VP(dentry->d_inode); 563 vp = LINVFS_GET_VP(dentry->d_inode);
523 564
524 iov.iov_base = link; 565 iov.iov_base = link;
525 iov.iov_len = MAXNAMELEN; 566 iov.iov_len = MAXPATHLEN;
526 567
527 uio->uio_iov = &iov; 568 uio->uio_iov = &iov;
528 uio->uio_offset = 0; 569 uio->uio_offset = 0;
529 uio->uio_segflg = UIO_SYSSPACE; 570 uio->uio_segflg = UIO_SYSSPACE;
530 uio->uio_resid = MAXNAMELEN; 571 uio->uio_resid = MAXPATHLEN;
531 uio->uio_iovcnt = 1; 572 uio->uio_iovcnt = 1;
532 573
533 VOP_READLINK(vp, uio, 0, NULL, error); 574 VOP_READLINK(vp, uio, 0, NULL, error);
@@ -535,7 +576,7 @@ linvfs_follow_link(
535 kfree(link); 576 kfree(link);
536 link = ERR_PTR(-error); 577 link = ERR_PTR(-error);
537 } else { 578 } else {
538 link[MAXNAMELEN - uio->uio_resid] = '\0'; 579 link[MAXPATHLEN - uio->uio_resid] = '\0';
539 } 580 }
540 kfree(uio); 581 kfree(uio);
541 582