[PATCH] per-mountpoint noatime/nodiratime
[safe/jmp/linux-2.6] / fs / xfs / linux-2.6 / xfs_iops.c
1 /*
2  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_bit.h"
21 #include "xfs_log.h"
22 #include "xfs_inum.h"
23 #include "xfs_trans.h"
24 #include "xfs_sb.h"
25 #include "xfs_ag.h"
26 #include "xfs_dir.h"
27 #include "xfs_dir2.h"
28 #include "xfs_alloc.h"
29 #include "xfs_dmapi.h"
30 #include "xfs_quota.h"
31 #include "xfs_mount.h"
32 #include "xfs_bmap_btree.h"
33 #include "xfs_alloc_btree.h"
34 #include "xfs_ialloc_btree.h"
35 #include "xfs_dir_sf.h"
36 #include "xfs_dir2_sf.h"
37 #include "xfs_attr_sf.h"
38 #include "xfs_dinode.h"
39 #include "xfs_inode.h"
40 #include "xfs_bmap.h"
41 #include "xfs_btree.h"
42 #include "xfs_ialloc.h"
43 #include "xfs_rtalloc.h"
44 #include "xfs_error.h"
45 #include "xfs_itable.h"
46 #include "xfs_rw.h"
47 #include "xfs_acl.h"
48 #include "xfs_cap.h"
49 #include "xfs_mac.h"
50 #include "xfs_attr.h"
51 #include "xfs_buf_item.h"
52 #include "xfs_utils.h"
53
54 #include <linux/xattr.h>
55 #include <linux/namei.h>
56
57 #define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) ||       \
58         (S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME))
59
60 /*
61  * Change the requested timestamp in the given inode.
62  * We don't lock across timestamp updates, and we don't log them but
63  * we do record the fact that there is dirty information in core.
64  *
65  * NOTE -- callers MUST combine XFS_ICHGTIME_MOD or XFS_ICHGTIME_CHG
66  *              with XFS_ICHGTIME_ACC to be sure that access time
67  *              update will take.  Calling first with XFS_ICHGTIME_ACC
68  *              and then XFS_ICHGTIME_MOD may fail to modify the access
69  *              timestamp if the filesystem is mounted noacctm.
70  */
71 void
72 xfs_ichgtime(
73         xfs_inode_t     *ip,
74         int             flags)
75 {
76         struct inode    *inode = LINVFS_GET_IP(XFS_ITOV(ip));
77         timespec_t      tv;
78
79         /*
80          * We're not supposed to change timestamps in readonly-mounted
81          * filesystems.  Throw it away if anyone asks us.
82          */
83         if (unlikely(IS_RDONLY(inode)))
84                 return;
85
86         /*
87          * Don't update access timestamps on reads if mounted "noatime".
88          * Throw it away if anyone asks us.
89          */
90         if (unlikely(
91             (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
92             (flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
93                         XFS_ICHGTIME_ACC))
94                 return;
95
96         nanotime(&tv);
97         if (flags & XFS_ICHGTIME_MOD) {
98                 inode->i_mtime = tv;
99                 ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec;
100                 ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec;
101         }
102         if (flags & XFS_ICHGTIME_ACC) {
103                 inode->i_atime = tv;
104                 ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec;
105                 ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec;
106         }
107         if (flags & XFS_ICHGTIME_CHG) {
108                 inode->i_ctime = tv;
109                 ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec;
110                 ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec;
111         }
112
113         /*
114          * We update the i_update_core field _after_ changing
115          * the timestamps in order to coordinate properly with
116          * xfs_iflush() so that we don't lose timestamp updates.
117          * This keeps us from having to hold the inode lock
118          * while doing this.  We use the SYNCHRONIZE macro to
119          * ensure that the compiler does not reorder the update
120          * of i_update_core above the timestamp updates above.
121          */
122         SYNCHRONIZE();
123         ip->i_update_core = 1;
124         if (!(inode->i_state & I_LOCK))
125                 mark_inode_dirty_sync(inode);
126 }
127
128 /*
129  * Variant on the above which avoids querying the system clock
130  * in situations where we know the Linux inode timestamps have
131  * just been updated (and so we can update our inode cheaply).
132  * We also skip the readonly and noatime checks here, they are
133  * also catered for already.
134  */
135 void
136 xfs_ichgtime_fast(
137         xfs_inode_t     *ip,
138         struct inode    *inode,
139         int             flags)
140 {
141         timespec_t      *tvp;
142
143         /*
144          * We're not supposed to change timestamps in readonly-mounted
145          * filesystems.  Throw it away if anyone asks us.
146          */
147         if (unlikely(IS_RDONLY(inode)))
148                 return;
149
150         /*
151          * Don't update access timestamps on reads if mounted "noatime".
152          * Throw it away if anyone asks us.
153          */
154         if (unlikely(
155             (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
156             ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
157                         XFS_ICHGTIME_ACC)))
158                 return;
159
160         if (flags & XFS_ICHGTIME_MOD) {
161                 tvp = &inode->i_mtime;
162                 ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec;
163                 ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec;
164         }
165         if (flags & XFS_ICHGTIME_ACC) {
166                 tvp = &inode->i_atime;
167                 ip->i_d.di_atime.t_sec = (__int32_t)tvp->tv_sec;
168                 ip->i_d.di_atime.t_nsec = (__int32_t)tvp->tv_nsec;
169         }
170         if (flags & XFS_ICHGTIME_CHG) {
171                 tvp = &inode->i_ctime;
172                 ip->i_d.di_ctime.t_sec = (__int32_t)tvp->tv_sec;
173                 ip->i_d.di_ctime.t_nsec = (__int32_t)tvp->tv_nsec;
174         }
175
176         /*
177          * We update the i_update_core field _after_ changing
178          * the timestamps in order to coordinate properly with
179          * xfs_iflush() so that we don't lose timestamp updates.
180          * This keeps us from having to hold the inode lock
181          * while doing this.  We use the SYNCHRONIZE macro to
182          * ensure that the compiler does not reorder the update
183          * of i_update_core above the timestamp updates above.
184          */
185         SYNCHRONIZE();
186         ip->i_update_core = 1;
187         if (!(inode->i_state & I_LOCK))
188                 mark_inode_dirty_sync(inode);
189 }
190
191
192 /*
193  * Pull the link count and size up from the xfs inode to the linux inode
194  */
195 STATIC void
196 validate_fields(
197         struct inode    *ip)
198 {
199         vnode_t         *vp = LINVFS_GET_VP(ip);
200         vattr_t         va;
201         int             error;
202
203         va.va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
204         VOP_GETATTR(vp, &va, ATTR_LAZY, NULL, error);
205         if (likely(!error)) {
206                 ip->i_nlink = va.va_nlink;
207                 ip->i_blocks = va.va_nblocks;
208
209                 /* we're under i_mutex so i_size can't change under us */
210                 if (i_size_read(ip) != va.va_size)
211                         i_size_write(ip, va.va_size);
212         }
213 }
214
215 /*
216  * Determine whether a process has a valid fs_struct (kernel daemons
217  * like knfsd don't have an fs_struct).
218  *
219  * XXX(hch):  nfsd is broken, better fix it instead.
220  */
221 STATIC inline int
222 has_fs_struct(struct task_struct *task)
223 {
224         return (task->fs != init_task.fs);
225 }
226
227 STATIC int
228 linvfs_mknod(
229         struct inode    *dir,
230         struct dentry   *dentry,
231         int             mode,
232         dev_t           rdev)
233 {
234         struct inode    *ip;
235         vattr_t         va;
236         vnode_t         *vp = NULL, *dvp = LINVFS_GET_VP(dir);
237         xfs_acl_t       *default_acl = NULL;
238         attrexists_t    test_default_acl = _ACL_DEFAULT_EXISTS;
239         int             error;
240
241         /*
242          * Irix uses Missed'em'V split, but doesn't want to see
243          * the upper 5 bits of (14bit) major.
244          */
245         if (!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)
246                 return -EINVAL;
247
248         if (test_default_acl && test_default_acl(dvp)) {
249                 if (!_ACL_ALLOC(default_acl))
250                         return -ENOMEM;
251                 if (!_ACL_GET_DEFAULT(dvp, default_acl)) {
252                         _ACL_FREE(default_acl);
253                         default_acl = NULL;
254                 }
255         }
256
257         if (IS_POSIXACL(dir) && !default_acl && has_fs_struct(current))
258                 mode &= ~current->fs->umask;
259
260         memset(&va, 0, sizeof(va));
261         va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
262         va.va_mode = mode;
263
264         switch (mode & S_IFMT) {
265         case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
266                 va.va_rdev = sysv_encode_dev(rdev);
267                 va.va_mask |= XFS_AT_RDEV;
268                 /*FALLTHROUGH*/
269         case S_IFREG:
270                 VOP_CREATE(dvp, dentry, &va, &vp, NULL, error);
271                 break;
272         case S_IFDIR:
273                 VOP_MKDIR(dvp, dentry, &va, &vp, NULL, error);
274                 break;
275         default:
276                 error = EINVAL;
277                 break;
278         }
279
280         if (default_acl) {
281                 if (!error) {
282                         error = _ACL_INHERIT(vp, &va, default_acl);
283                         if (!error) {
284                                 VMODIFY(vp);
285                         } else {
286                                 struct dentry   teardown = {};
287                                 int             err2;
288
289                                 /* Oh, the horror.
290                                  * If we can't add the ACL we must back out.
291                                  * ENOSPC can hit here, among other things.
292                                  */
293                                 teardown.d_inode = ip = LINVFS_GET_IP(vp);
294                                 teardown.d_name = dentry->d_name;
295
296                                 vn_mark_bad(vp);
297                                 
298                                 if (S_ISDIR(mode))
299                                         VOP_RMDIR(dvp, &teardown, NULL, err2);
300                                 else
301                                         VOP_REMOVE(dvp, &teardown, NULL, err2);
302                                 VN_RELE(vp);
303                         }
304                 }
305                 _ACL_FREE(default_acl);
306         }
307
308         if (!error) {
309                 ASSERT(vp);
310                 ip = LINVFS_GET_IP(vp);
311
312                 if (S_ISCHR(mode) || S_ISBLK(mode))
313                         ip->i_rdev = rdev;
314                 else if (S_ISDIR(mode))
315                         validate_fields(ip);
316                 d_instantiate(dentry, ip);
317                 validate_fields(dir);
318         }
319         return -error;
320 }
321
322 STATIC int
323 linvfs_create(
324         struct inode    *dir,
325         struct dentry   *dentry,
326         int             mode,
327         struct nameidata *nd)
328 {
329         return linvfs_mknod(dir, dentry, mode, 0);
330 }
331
332 STATIC int
333 linvfs_mkdir(
334         struct inode    *dir,
335         struct dentry   *dentry,
336         int             mode)
337 {
338         return linvfs_mknod(dir, dentry, mode|S_IFDIR, 0);
339 }
340
341 STATIC struct dentry *
342 linvfs_lookup(
343         struct inode    *dir,
344         struct dentry   *dentry,
345         struct nameidata *nd)
346 {
347         struct vnode    *vp = LINVFS_GET_VP(dir), *cvp;
348         int             error;
349
350         if (dentry->d_name.len >= MAXNAMELEN)
351                 return ERR_PTR(-ENAMETOOLONG);
352
353         VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error);
354         if (error) {
355                 if (unlikely(error != ENOENT))
356                         return ERR_PTR(-error);
357                 d_add(dentry, NULL);
358                 return NULL;
359         }
360
361         return d_splice_alias(LINVFS_GET_IP(cvp), dentry);
362 }
363
364 STATIC int
365 linvfs_link(
366         struct dentry   *old_dentry,
367         struct inode    *dir,
368         struct dentry   *dentry)
369 {
370         struct inode    *ip;    /* inode of guy being linked to */
371         vnode_t         *tdvp;  /* target directory for new name/link */
372         vnode_t         *vp;    /* vp of name being linked */
373         int             error;
374
375         ip = old_dentry->d_inode;       /* inode being linked to */
376         if (S_ISDIR(ip->i_mode))
377                 return -EPERM;
378
379         tdvp = LINVFS_GET_VP(dir);
380         vp = LINVFS_GET_VP(ip);
381
382         VOP_LINK(tdvp, vp, dentry, NULL, error);
383         if (!error) {
384                 VMODIFY(tdvp);
385                 VN_HOLD(vp);
386                 validate_fields(ip);
387                 d_instantiate(dentry, ip);
388         }
389         return -error;
390 }
391
392 STATIC int
393 linvfs_unlink(
394         struct inode    *dir,
395         struct dentry   *dentry)
396 {
397         struct inode    *inode;
398         vnode_t         *dvp;   /* directory containing name to remove */
399         int             error;
400
401         inode = dentry->d_inode;
402         dvp = LINVFS_GET_VP(dir);
403
404         VOP_REMOVE(dvp, dentry, NULL, error);
405         if (!error) {
406                 validate_fields(dir);   /* For size only */
407                 validate_fields(inode);
408         }
409
410         return -error;
411 }
412
413 STATIC int
414 linvfs_symlink(
415         struct inode    *dir,
416         struct dentry   *dentry,
417         const char      *symname)
418 {
419         struct inode    *ip;
420         vattr_t         va;
421         vnode_t         *dvp;   /* directory containing name of symlink */
422         vnode_t         *cvp;   /* used to lookup symlink to put in dentry */
423         int             error;
424
425         dvp = LINVFS_GET_VP(dir);
426         cvp = NULL;
427
428         memset(&va, 0, sizeof(va));
429         va.va_mode = S_IFLNK |
430                 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
431         va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
432
433         error = 0;
434         VOP_SYMLINK(dvp, dentry, &va, (char *)symname, &cvp, NULL, error);
435         if (!error && cvp) {
436                 ip = LINVFS_GET_IP(cvp);
437                 d_instantiate(dentry, ip);
438                 validate_fields(dir);
439                 validate_fields(ip); /* size needs update */
440         }
441         return -error;
442 }
443
444 STATIC int
445 linvfs_rmdir(
446         struct inode    *dir,
447         struct dentry   *dentry)
448 {
449         struct inode    *inode = dentry->d_inode;
450         vnode_t         *dvp = LINVFS_GET_VP(dir);
451         int             error;
452
453         VOP_RMDIR(dvp, dentry, NULL, error);
454         if (!error) {
455                 validate_fields(inode);
456                 validate_fields(dir);
457         }
458         return -error;
459 }
460
461 STATIC int
462 linvfs_rename(
463         struct inode    *odir,
464         struct dentry   *odentry,
465         struct inode    *ndir,
466         struct dentry   *ndentry)
467 {
468         struct inode    *new_inode = ndentry->d_inode;
469         vnode_t         *fvp;   /* from directory */
470         vnode_t         *tvp;   /* target directory */
471         int             error;
472
473         fvp = LINVFS_GET_VP(odir);
474         tvp = LINVFS_GET_VP(ndir);
475
476         VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error);
477         if (error)
478                 return -error;
479
480         if (new_inode)
481                 validate_fields(new_inode);
482
483         validate_fields(odir);
484         if (ndir != odir)
485                 validate_fields(ndir);
486         return 0;
487 }
488
489 /*
490  * careful here - this function can get called recursively, so
491  * we need to be very careful about how much stack we use.
492  * uio is kmalloced for this reason...
493  */
494 STATIC void *
495 linvfs_follow_link(
496         struct dentry           *dentry,
497         struct nameidata        *nd)
498 {
499         vnode_t                 *vp;
500         uio_t                   *uio;
501         iovec_t                 iov;
502         int                     error;
503         char                    *link;
504
505         ASSERT(dentry);
506         ASSERT(nd);
507
508         link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL);
509         if (!link) {
510                 nd_set_link(nd, ERR_PTR(-ENOMEM));
511                 return NULL;
512         }
513
514         uio = (uio_t *)kmalloc(sizeof(uio_t), GFP_KERNEL);
515         if (!uio) {
516                 kfree(link);
517                 nd_set_link(nd, ERR_PTR(-ENOMEM));
518                 return NULL;
519         }
520
521         vp = LINVFS_GET_VP(dentry->d_inode);
522
523         iov.iov_base = link;
524         iov.iov_len = MAXNAMELEN;
525
526         uio->uio_iov = &iov;
527         uio->uio_offset = 0;
528         uio->uio_segflg = UIO_SYSSPACE;
529         uio->uio_resid = MAXNAMELEN;
530         uio->uio_iovcnt = 1;
531
532         VOP_READLINK(vp, uio, 0, NULL, error);
533         if (error) {
534                 kfree(link);
535                 link = ERR_PTR(-error);
536         } else {
537                 link[MAXNAMELEN - uio->uio_resid] = '\0';
538         }
539         kfree(uio);
540
541         nd_set_link(nd, link);
542         return NULL;
543 }
544
545 STATIC void
546 linvfs_put_link(
547         struct dentry   *dentry,
548         struct nameidata *nd,
549         void            *p)
550 {
551         char            *s = nd_get_link(nd);
552
553         if (!IS_ERR(s))
554                 kfree(s);
555 }
556
557 #ifdef CONFIG_XFS_POSIX_ACL
558 STATIC int
559 linvfs_permission(
560         struct inode    *inode,
561         int             mode,
562         struct nameidata *nd)
563 {
564         vnode_t         *vp = LINVFS_GET_VP(inode);
565         int             error;
566
567         mode <<= 6;             /* convert from linux to vnode access bits */
568         VOP_ACCESS(vp, mode, NULL, error);
569         return -error;
570 }
571 #else
572 #define linvfs_permission NULL
573 #endif
574
575 STATIC int
576 linvfs_getattr(
577         struct vfsmount *mnt,
578         struct dentry   *dentry,
579         struct kstat    *stat)
580 {
581         struct inode    *inode = dentry->d_inode;
582         vnode_t         *vp = LINVFS_GET_VP(inode);
583         int             error = 0;
584
585         if (unlikely(vp->v_flag & VMODIFIED))
586                 error = vn_revalidate(vp);
587         if (!error)
588                 generic_fillattr(inode, stat);
589         return 0;
590 }
591
592 STATIC int
593 linvfs_setattr(
594         struct dentry   *dentry,
595         struct iattr    *attr)
596 {
597         struct inode    *inode = dentry->d_inode;
598         unsigned int    ia_valid = attr->ia_valid;
599         vnode_t         *vp = LINVFS_GET_VP(inode);
600         vattr_t         vattr;
601         int             flags = 0;
602         int             error;
603
604         memset(&vattr, 0, sizeof(vattr_t));
605         if (ia_valid & ATTR_UID) {
606                 vattr.va_mask |= XFS_AT_UID;
607                 vattr.va_uid = attr->ia_uid;
608         }
609         if (ia_valid & ATTR_GID) {
610                 vattr.va_mask |= XFS_AT_GID;
611                 vattr.va_gid = attr->ia_gid;
612         }
613         if (ia_valid & ATTR_SIZE) {
614                 vattr.va_mask |= XFS_AT_SIZE;
615                 vattr.va_size = attr->ia_size;
616         }
617         if (ia_valid & ATTR_ATIME) {
618                 vattr.va_mask |= XFS_AT_ATIME;
619                 vattr.va_atime = attr->ia_atime;
620         }
621         if (ia_valid & ATTR_MTIME) {
622                 vattr.va_mask |= XFS_AT_MTIME;
623                 vattr.va_mtime = attr->ia_mtime;
624         }
625         if (ia_valid & ATTR_CTIME) {
626                 vattr.va_mask |= XFS_AT_CTIME;
627                 vattr.va_ctime = attr->ia_ctime;
628         }
629         if (ia_valid & ATTR_MODE) {
630                 vattr.va_mask |= XFS_AT_MODE;
631                 vattr.va_mode = attr->ia_mode;
632                 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
633                         inode->i_mode &= ~S_ISGID;
634         }
635
636         if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET))
637                 flags |= ATTR_UTIME;
638 #ifdef ATTR_NO_BLOCK
639         if ((ia_valid & ATTR_NO_BLOCK))
640                 flags |= ATTR_NONBLOCK;
641 #endif
642
643         VOP_SETATTR(vp, &vattr, flags, NULL, error);
644         if (error)
645                 return -error;
646         vn_revalidate(vp);
647         return error;
648 }
649
650 STATIC void
651 linvfs_truncate(
652         struct inode    *inode)
653 {
654         block_truncate_page(inode->i_mapping, inode->i_size, linvfs_get_block);
655 }
656
657 STATIC int
658 linvfs_setxattr(
659         struct dentry   *dentry,
660         const char      *name,
661         const void      *data,
662         size_t          size,
663         int             flags)
664 {
665         vnode_t         *vp = LINVFS_GET_VP(dentry->d_inode);
666         char            *attr = (char *)name;
667         attrnames_t     *namesp;
668         int             xflags = 0;
669         int             error;
670
671         namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
672         if (!namesp)
673                 return -EOPNOTSUPP;
674         attr += namesp->attr_namelen;
675         error = namesp->attr_capable(vp, NULL);
676         if (error)
677                 return error;
678
679         /* Convert Linux syscall to XFS internal ATTR flags */
680         if (flags & XATTR_CREATE)
681                 xflags |= ATTR_CREATE;
682         if (flags & XATTR_REPLACE)
683                 xflags |= ATTR_REPLACE;
684         xflags |= namesp->attr_flag;
685         return namesp->attr_set(vp, attr, (void *)data, size, xflags);
686 }
687
688 STATIC ssize_t
689 linvfs_getxattr(
690         struct dentry   *dentry,
691         const char      *name,
692         void            *data,
693         size_t          size)
694 {
695         vnode_t         *vp = LINVFS_GET_VP(dentry->d_inode);
696         char            *attr = (char *)name;
697         attrnames_t     *namesp;
698         int             xflags = 0;
699         ssize_t         error;
700
701         namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
702         if (!namesp)
703                 return -EOPNOTSUPP;
704         attr += namesp->attr_namelen;
705         error = namesp->attr_capable(vp, NULL);
706         if (error)
707                 return error;
708
709         /* Convert Linux syscall to XFS internal ATTR flags */
710         if (!size) {
711                 xflags |= ATTR_KERNOVAL;
712                 data = NULL;
713         }
714         xflags |= namesp->attr_flag;
715         return namesp->attr_get(vp, attr, (void *)data, size, xflags);
716 }
717
718 STATIC ssize_t
719 linvfs_listxattr(
720         struct dentry           *dentry,
721         char                    *data,
722         size_t                  size)
723 {
724         vnode_t                 *vp = LINVFS_GET_VP(dentry->d_inode);
725         int                     error, xflags = ATTR_KERNAMELS;
726         ssize_t                 result;
727
728         if (!size)
729                 xflags |= ATTR_KERNOVAL;
730         xflags |= capable(CAP_SYS_ADMIN) ? ATTR_KERNFULLS : ATTR_KERNORMALS;
731
732         error = attr_generic_list(vp, data, size, xflags, &result);
733         if (error < 0)
734                 return error;
735         return result;
736 }
737
738 STATIC int
739 linvfs_removexattr(
740         struct dentry   *dentry,
741         const char      *name)
742 {
743         vnode_t         *vp = LINVFS_GET_VP(dentry->d_inode);
744         char            *attr = (char *)name;
745         attrnames_t     *namesp;
746         int             xflags = 0;
747         int             error;
748
749         namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
750         if (!namesp)
751                 return -EOPNOTSUPP;
752         attr += namesp->attr_namelen;
753         error = namesp->attr_capable(vp, NULL);
754         if (error)
755                 return error;
756         xflags |= namesp->attr_flag;
757         return namesp->attr_remove(vp, attr, xflags);
758 }
759
760
761 struct inode_operations linvfs_file_inode_operations = {
762         .permission             = linvfs_permission,
763         .truncate               = linvfs_truncate,
764         .getattr                = linvfs_getattr,
765         .setattr                = linvfs_setattr,
766         .setxattr               = linvfs_setxattr,
767         .getxattr               = linvfs_getxattr,
768         .listxattr              = linvfs_listxattr,
769         .removexattr            = linvfs_removexattr,
770 };
771
772 struct inode_operations linvfs_dir_inode_operations = {
773         .create                 = linvfs_create,
774         .lookup                 = linvfs_lookup,
775         .link                   = linvfs_link,
776         .unlink                 = linvfs_unlink,
777         .symlink                = linvfs_symlink,
778         .mkdir                  = linvfs_mkdir,
779         .rmdir                  = linvfs_rmdir,
780         .mknod                  = linvfs_mknod,
781         .rename                 = linvfs_rename,
782         .permission             = linvfs_permission,
783         .getattr                = linvfs_getattr,
784         .setattr                = linvfs_setattr,
785         .setxattr               = linvfs_setxattr,
786         .getxattr               = linvfs_getxattr,
787         .listxattr              = linvfs_listxattr,
788         .removexattr            = linvfs_removexattr,
789 };
790
791 struct inode_operations linvfs_symlink_inode_operations = {
792         .readlink               = generic_readlink,
793         .follow_link            = linvfs_follow_link,
794         .put_link               = linvfs_put_link,
795         .permission             = linvfs_permission,
796         .getattr                = linvfs_getattr,
797         .setattr                = linvfs_setattr,
798         .setxattr               = linvfs_setxattr,
799         .getxattr               = linvfs_getxattr,
800         .listxattr              = linvfs_listxattr,
801         .removexattr            = linvfs_removexattr,
802 };