aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_iops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_iops.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c127
1 files changed, 86 insertions, 41 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 14215a7db59f..4bd3d03b23ed 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -51,8 +51,47 @@
51#include "xfs_buf_item.h" 51#include "xfs_buf_item.h"
52#include "xfs_utils.h" 52#include "xfs_utils.h"
53 53
54#include <linux/capability.h>
54#include <linux/xattr.h> 55#include <linux/xattr.h>
55#include <linux/namei.h> 56#include <linux/namei.h>
57#include <linux/security.h>
58
59#define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) || \
60 (S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME))
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}
56 95
57/* 96/*
58 * Change the requested timestamp in the given inode. 97 * Change the requested timestamp in the given inode.
@@ -73,23 +112,6 @@ xfs_ichgtime(
73 struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip)); 112 struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));
74 timespec_t tv; 113 timespec_t tv;
75 114
76 /*
77 * We're not supposed to change timestamps in readonly-mounted
78 * filesystems. Throw it away if anyone asks us.
79 */
80 if (unlikely(IS_RDONLY(inode)))
81 return;
82
83 /*
84 * Don't update access timestamps on reads if mounted "noatime".
85 * Throw it away if anyone asks us.
86 */
87 if (unlikely(
88 (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
89 (flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
90 XFS_ICHGTIME_ACC))
91 return;
92
93 nanotime(&tv); 115 nanotime(&tv);
94 if (flags & XFS_ICHGTIME_MOD) { 116 if (flags & XFS_ICHGTIME_MOD) {
95 inode->i_mtime = tv; 117 inode->i_mtime = tv;
@@ -126,8 +148,6 @@ xfs_ichgtime(
126 * Variant on the above which avoids querying the system clock 148 * Variant on the above which avoids querying the system clock
127 * in situations where we know the Linux inode timestamps have 149 * in situations where we know the Linux inode timestamps have
128 * just been updated (and so we can update our inode cheaply). 150 * just been updated (and so we can update our inode cheaply).
129 * We also skip the readonly and noatime checks here, they are
130 * also catered for already.
131 */ 151 */
132void 152void
133xfs_ichgtime_fast( 153xfs_ichgtime_fast(
@@ -138,20 +158,16 @@ xfs_ichgtime_fast(
138 timespec_t *tvp; 158 timespec_t *tvp;
139 159
140 /* 160 /*
141 * We're not supposed to change timestamps in readonly-mounted 161 * Atime updates for read() & friends are handled lazily now, and
142 * filesystems. Throw it away if anyone asks us. 162 * explicit updates must go through xfs_ichgtime()
143 */ 163 */
144 if (unlikely(IS_RDONLY(inode))) 164 ASSERT((flags & XFS_ICHGTIME_ACC) == 0);
145 return;
146 165
147 /* 166 /*
148 * Don't update access timestamps on reads if mounted "noatime". 167 * We're not supposed to change timestamps in readonly-mounted
149 * Throw it away if anyone asks us. 168 * filesystems. Throw it away if anyone asks us.
150 */ 169 */
151 if (unlikely( 170 if (unlikely(IS_RDONLY(inode)))
152 (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
153 ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
154 XFS_ICHGTIME_ACC)))
155 return; 171 return;
156 172
157 if (flags & XFS_ICHGTIME_MOD) { 173 if (flags & XFS_ICHGTIME_MOD) {
@@ -159,11 +175,6 @@ xfs_ichgtime_fast(
159 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;
160 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;
161 } 177 }
162 if (flags & XFS_ICHGTIME_ACC) {
163 tvp = &inode->i_atime;
164 ip->i_d.di_atime.t_sec = (__int32_t)tvp->tv_sec;
165 ip->i_d.di_atime.t_nsec = (__int32_t)tvp->tv_nsec;
166 }
167 if (flags & XFS_ICHGTIME_CHG) { 178 if (flags & XFS_ICHGTIME_CHG) {
168 tvp = &inode->i_ctime; 179 tvp = &inode->i_ctime;
169 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;
@@ -203,13 +214,46 @@ validate_fields(
203 ip->i_nlink = va.va_nlink; 214 ip->i_nlink = va.va_nlink;
204 ip->i_blocks = va.va_nblocks; 215 ip->i_blocks = va.va_nblocks;
205 216
206 /* we're under i_sem so i_size can't change under us */ 217 /* we're under i_mutex so i_size can't change under us */
207 if (i_size_read(ip) != va.va_size) 218 if (i_size_read(ip) != va.va_size)
208 i_size_write(ip, va.va_size); 219 i_size_write(ip, va.va_size);
209 } 220 }
210} 221}
211 222
212/* 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/*
213 * Determine whether a process has a valid fs_struct (kernel daemons 257 * Determine whether a process has a valid fs_struct (kernel daemons
214 * like knfsd don't have an fs_struct). 258 * like knfsd don't have an fs_struct).
215 * 259 *
@@ -274,6 +318,9 @@ linvfs_mknod(
274 break; 318 break;
275 } 319 }
276 320
321 if (!error)
322 error = linvfs_init_security(vp, dir);
323
277 if (default_acl) { 324 if (default_acl) {
278 if (!error) { 325 if (!error) {
279 error = _ACL_INHERIT(vp, &va, default_acl); 326 error = _ACL_INHERIT(vp, &va, default_acl);
@@ -290,8 +337,6 @@ linvfs_mknod(
290 teardown.d_inode = ip = LINVFS_GET_IP(vp); 337 teardown.d_inode = ip = LINVFS_GET_IP(vp);
291 teardown.d_name = dentry->d_name; 338 teardown.d_name = dentry->d_name;
292 339
293 vn_mark_bad(vp);
294
295 if (S_ISDIR(mode)) 340 if (S_ISDIR(mode))
296 VOP_RMDIR(dvp, &teardown, NULL, err2); 341 VOP_RMDIR(dvp, &teardown, NULL, err2);
297 else 342 else
@@ -502,7 +547,7 @@ linvfs_follow_link(
502 ASSERT(dentry); 547 ASSERT(dentry);
503 ASSERT(nd); 548 ASSERT(nd);
504 549
505 link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL); 550 link = (char *)kmalloc(MAXPATHLEN+1, GFP_KERNEL);
506 if (!link) { 551 if (!link) {
507 nd_set_link(nd, ERR_PTR(-ENOMEM)); 552 nd_set_link(nd, ERR_PTR(-ENOMEM));
508 return NULL; 553 return NULL;
@@ -518,12 +563,12 @@ linvfs_follow_link(
518 vp = LINVFS_GET_VP(dentry->d_inode); 563 vp = LINVFS_GET_VP(dentry->d_inode);
519 564
520 iov.iov_base = link; 565 iov.iov_base = link;
521 iov.iov_len = MAXNAMELEN; 566 iov.iov_len = MAXPATHLEN;
522 567
523 uio->uio_iov = &iov; 568 uio->uio_iov = &iov;
524 uio->uio_offset = 0; 569 uio->uio_offset = 0;
525 uio->uio_segflg = UIO_SYSSPACE; 570 uio->uio_segflg = UIO_SYSSPACE;
526 uio->uio_resid = MAXNAMELEN; 571 uio->uio_resid = MAXPATHLEN;
527 uio->uio_iovcnt = 1; 572 uio->uio_iovcnt = 1;
528 573
529 VOP_READLINK(vp, uio, 0, NULL, error); 574 VOP_READLINK(vp, uio, 0, NULL, error);
@@ -531,7 +576,7 @@ linvfs_follow_link(
531 kfree(link); 576 kfree(link);
532 link = ERR_PTR(-error); 577 link = ERR_PTR(-error);
533 } else { 578 } else {
534 link[MAXNAMELEN - uio->uio_resid] = '\0'; 579 link[MAXPATHLEN - uio->uio_resid] = '\0';
535 } 580 }
536 kfree(uio); 581 kfree(uio);
537 582