[PATCH] r/o bind mounts: unlink: monitor i_nlink
[safe/jmp/linux-2.6] / fs / reiserfs / xattr.c
index f1895f0..d935fb9 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #include <linux/reiserfs_fs.h>
+#include <linux/capability.h>
 #include <linux/dcache.h>
 #include <linux/namei.h>
 #include <linux/errno.h>
@@ -367,15 +368,13 @@ static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir)
                if (d_reclen <= 32) {
                        local_buf = small_buf;
                } else {
-                       local_buf =
-                           reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb);
+                       local_buf = kmalloc(d_reclen, GFP_NOFS);
                        if (!local_buf) {
                                pathrelse(&path_to_entry);
                                return -ENOMEM;
                        }
                        if (item_moved(&tmp_ih, &path_to_entry)) {
-                               reiserfs_kfree(local_buf, d_reclen,
-                                              inode->i_sb);
+                               kfree(local_buf);
 
                                /* sigh, must retry.  Do this same offset again */
                                next_pos = d_off;
@@ -398,13 +397,12 @@ static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir)
                if (filldir(dirent, local_buf, d_reclen, d_off, d_ino,
                            DT_UNKNOWN) < 0) {
                        if (local_buf != small_buf) {
-                               reiserfs_kfree(local_buf, d_reclen,
-                                              inode->i_sb);
+                               kfree(local_buf);
                        }
                        goto end;
                }
                if (local_buf != small_buf) {
-                       reiserfs_kfree(local_buf, d_reclen, inode->i_sb);
+                       kfree(local_buf);
                }
        }                       /* while */
 
@@ -426,7 +424,7 @@ int xattr_readdir(struct file *file, filldir_t filler, void *buf)
        int res = -ENOTDIR;
        if (!file->f_op || !file->f_op->readdir)
                goto out;
-       mutex_lock(&inode->i_mutex);
+       mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR);
 //        down(&inode->i_zombie);
        res = -ENOENT;
        if (!IS_DEADDIR(inode)) {
@@ -454,8 +452,7 @@ static struct page *reiserfs_get_page(struct inode *dir, unsigned long n)
        /* We can deadlock if we try to free dentries,
           and an unlink/rmdir has just occured - GFP_NOFS avoids this */
        mapping_set_gfp_mask(mapping, GFP_NOFS);
-       page = read_cache_page(mapping, n,
-                              (filler_t *) mapping->a_ops->readpage, NULL);
+       page = read_mapping_page(mapping, n, NULL);
        if (!IS_ERR(page)) {
                wait_on_page_locked(page);
                kmap(page);
@@ -497,12 +494,6 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
        struct iattr newattrs;
        __u32 xahash = 0;
 
-       if (IS_RDONLY(inode))
-               return -EROFS;
-
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               return -EPERM;
-
        if (get_inode_sd_version(inode) == STAT_DATA_V1)
                return -EOPNOTSUPP;
 
@@ -758,9 +749,6 @@ int reiserfs_xattr_del(struct inode *inode, const char *name)
        struct dentry *dir;
        int err;
 
-       if (IS_RDONLY(inode))
-               return -EROFS;
-
        dir = open_xa_dir(inode, FL_READONLY);
        if (IS_ERR(dir)) {
                err = PTR_ERR(dir);
@@ -984,12 +972,6 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,
            get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
                return -EOPNOTSUPP;
 
-       if (IS_RDONLY(dentry->d_inode))
-               return -EROFS;
-
-       if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode))
-               return -EROFS;
-
        reiserfs_write_lock_xattr_i(dentry->d_inode);
        lock = !has_xattr_dir(dentry->d_inode);
        if (lock)
@@ -1019,12 +1001,6 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name)
            get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
                return -EOPNOTSUPP;
 
-       if (IS_RDONLY(dentry->d_inode))
-               return -EROFS;
-
-       if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode))
-               return -EPERM;
-
        reiserfs_write_lock_xattr_i(dentry->d_inode);
        reiserfs_read_lock_xattrs(dentry->d_sb);
 
@@ -1342,109 +1318,44 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
        return err;
 }
 
-static int
-__reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd,
-                     int need_lock)
+static int reiserfs_check_acl(struct inode *inode, int mask)
 {
-       umode_t mode = inode->i_mode;
+       struct posix_acl *acl;
+       int error = -EAGAIN; /* do regular unix permission checks by default */
 
-       if (mask & MAY_WRITE) {
-               /*
-                * Nobody gets write access to a read-only fs.
-                */
-               if (IS_RDONLY(inode) &&
-                   (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-                       return -EROFS;
-
-               /*
-                * Nobody gets write access to an immutable file.
-                */
-               if (IS_IMMUTABLE(inode))
-                       return -EACCES;
-       }
+       reiserfs_read_lock_xattr_i(inode);
+       reiserfs_read_lock_xattrs(inode->i_sb);
 
-       /* We don't do permission checks on the internal objects.
-        * Permissions are determined by the "owning" object. */
-       if (is_reiserfs_priv_object(inode))
-               return 0;
+       acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
 
-       if (current->fsuid == inode->i_uid) {
-               mode >>= 6;
-#ifdef CONFIG_REISERFS_FS_POSIX_ACL
-       } else if (reiserfs_posixacl(inode->i_sb) &&
-                  get_inode_sd_version(inode) != STAT_DATA_V1) {
-               struct posix_acl *acl;
-
-               /* ACL can't contain additional permissions if
-                  the ACL_MASK entry is 0 */
-               if (!(mode & S_IRWXG))
-                       goto check_groups;
-
-               if (need_lock) {
-                       reiserfs_read_lock_xattr_i(inode);
-                       reiserfs_read_lock_xattrs(inode->i_sb);
-               }
-               acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
-               if (need_lock) {
-                       reiserfs_read_unlock_xattrs(inode->i_sb);
-                       reiserfs_read_unlock_xattr_i(inode);
-               }
-               if (IS_ERR(acl)) {
-                       if (PTR_ERR(acl) == -ENODATA)
-                               goto check_groups;
-                       return PTR_ERR(acl);
-               }
+       reiserfs_read_unlock_xattrs(inode->i_sb);
+       reiserfs_read_unlock_xattr_i(inode);
 
-               if (acl) {
-                       int err = posix_acl_permission(inode, acl, mask);
+       if (acl) {
+               if (!IS_ERR(acl)) {
+                       error = posix_acl_permission(inode, acl, mask);
                        posix_acl_release(acl);
-                       if (err == -EACCES) {
-                               goto check_capabilities;
-                       }
-                       return err;
-               } else {
-                       goto check_groups;
-               }
-#endif
-       } else {
-             check_groups:
-               if (in_group_p(inode->i_gid))
-                       mode >>= 3;
+               } else if (PTR_ERR(acl) != -ENODATA)
+                       error = PTR_ERR(acl);
        }
 
-       /*
-        * If the DACs are ok we don't need any capability check.
-        */
-       if (((mode & mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == mask))
-               return 0;
+       return error;
+}
 
-      check_capabilities:
+int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
        /*
-        * Read/write DACs are always overridable.
-        * Executable DACs are overridable if at least one exec bit is set.
+        * We don't do permission checks on the internal objects.
+        * Permissions are determined by the "owning" object.
         */
-       if (!(mask & MAY_EXEC) ||
-           (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
-               if (capable(CAP_DAC_OVERRIDE))
-                       return 0;
+       if (is_reiserfs_priv_object(inode))
+               return 0;
 
        /*
-        * Searching includes executable on directories, else just read.
+        * Stat data v1 doesn't support ACLs.
         */
-       if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
-               if (capable(CAP_DAC_READ_SEARCH))
-                       return 0;
-
-       return -EACCES;
-}
-
-int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd)
-{
-       return __reiserfs_permission(inode, mask, nd, 1);
-}
-
-int
-reiserfs_permission_locked(struct inode *inode, int mask, struct nameidata *nd)
-{
-       return __reiserfs_permission(inode, mask, nd, 0);
+       if (get_inode_sd_version(inode) == STAT_DATA_V1)
+               return generic_permission(inode, mask, NULL);
+       else
+               return generic_permission(inode, mask, reiserfs_check_acl);
 }