Merge branch 'writeback' of git://git.kernel.dk/linux-2.6-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 11 Sep 2009 16:17:05 +0000 (09:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 11 Sep 2009 16:17:05 +0000 (09:17 -0700)
* 'writeback' of git://git.kernel.dk/linux-2.6-block:
  writeback: check for registered bdi in flusher add and inode dirty
  writeback: add name to backing_dev_info
  writeback: add some debug inode list counters to bdi stats
  writeback: get rid of pdflush completely
  writeback: switch to per-bdi threads for flushing data
  writeback: move dirty inodes from super_block to backing_dev_info
  writeback: get rid of generic_sync_sb_inodes() export

1  2 
fs/sysfs/inode.c

diff --combined fs/sysfs/inode.c
@@@ -18,8 -18,6 +18,8 @@@
  #include <linux/capability.h>
  #include <linux/errno.h>
  #include <linux/sched.h>
 +#include <linux/xattr.h>
 +#include <linux/security.h>
  #include "sysfs.h"
  
  extern struct super_block * sysfs_sb;
@@@ -31,13 -29,13 +31,14 @@@ static const struct address_space_opera
  };
  
  static struct backing_dev_info sysfs_backing_dev_info = {
+       .name           = "sysfs",
        .ra_pages       = 0,    /* No readahead */
        .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK,
  };
  
  static const struct inode_operations sysfs_inode_operations ={
        .setattr        = sysfs_setattr,
 +      .setxattr       = sysfs_setxattr,
  };
  
  int __init sysfs_inode_init(void)
        return bdi_init(&sysfs_backing_dev_info);
  }
  
 +struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd)
 +{
 +      struct sysfs_inode_attrs *attrs;
 +      struct iattr *iattrs;
 +
 +      attrs = kzalloc(sizeof(struct sysfs_inode_attrs), GFP_KERNEL);
 +      if (!attrs)
 +              return NULL;
 +      iattrs = &attrs->ia_iattr;
 +
 +      /* assign default attributes */
 +      iattrs->ia_mode = sd->s_mode;
 +      iattrs->ia_uid = 0;
 +      iattrs->ia_gid = 0;
 +      iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME;
 +
 +      return attrs;
 +}
  int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
  {
        struct inode * inode = dentry->d_inode;
        struct sysfs_dirent * sd = dentry->d_fsdata;
 -      struct iattr * sd_iattr;
 +      struct sysfs_inode_attrs *sd_attrs;
 +      struct iattr *iattrs;
        unsigned int ia_valid = iattr->ia_valid;
        int error;
  
        if (!sd)
                return -EINVAL;
  
 -      sd_iattr = sd->s_iattr;
 +      sd_attrs = sd->s_iattr;
  
        error = inode_change_ok(inode, iattr);
        if (error)
        if (error)
                return error;
  
 -      if (!sd_iattr) {
 +      if (!sd_attrs) {
                /* setting attributes for the first time, allocate now */
 -              sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
 -              if (!sd_iattr)
 +              sd_attrs = sysfs_init_inode_attrs(sd);
 +              if (!sd_attrs)
                        return -ENOMEM;
 -              /* assign default attributes */
 -              sd_iattr->ia_mode = sd->s_mode;
 -              sd_iattr->ia_uid = 0;
 -              sd_iattr->ia_gid = 0;
 -              sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME;
 -              sd->s_iattr = sd_iattr;
 +              sd->s_iattr = sd_attrs;
 +      } else {
 +              /* attributes were changed at least once in past */
 +              iattrs = &sd_attrs->ia_iattr;
 +
 +              if (ia_valid & ATTR_UID)
 +                      iattrs->ia_uid = iattr->ia_uid;
 +              if (ia_valid & ATTR_GID)
 +                      iattrs->ia_gid = iattr->ia_gid;
 +              if (ia_valid & ATTR_ATIME)
 +                      iattrs->ia_atime = timespec_trunc(iattr->ia_atime,
 +                                      inode->i_sb->s_time_gran);
 +              if (ia_valid & ATTR_MTIME)
 +                      iattrs->ia_mtime = timespec_trunc(iattr->ia_mtime,
 +                                      inode->i_sb->s_time_gran);
 +              if (ia_valid & ATTR_CTIME)
 +                      iattrs->ia_ctime = timespec_trunc(iattr->ia_ctime,
 +                                      inode->i_sb->s_time_gran);
 +              if (ia_valid & ATTR_MODE) {
 +                      umode_t mode = iattr->ia_mode;
 +
 +                      if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
 +                              mode &= ~S_ISGID;
 +                      iattrs->ia_mode = sd->s_mode = mode;
 +              }
        }
 +      return error;
 +}
  
 -      /* attributes were changed atleast once in past */
 -
 -      if (ia_valid & ATTR_UID)
 -              sd_iattr->ia_uid = iattr->ia_uid;
 -      if (ia_valid & ATTR_GID)
 -              sd_iattr->ia_gid = iattr->ia_gid;
 -      if (ia_valid & ATTR_ATIME)
 -              sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime,
 -                                              inode->i_sb->s_time_gran);
 -      if (ia_valid & ATTR_MTIME)
 -              sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime,
 -                                              inode->i_sb->s_time_gran);
 -      if (ia_valid & ATTR_CTIME)
 -              sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime,
 -                                              inode->i_sb->s_time_gran);
 -      if (ia_valid & ATTR_MODE) {
 -              umode_t mode = iattr->ia_mode;
 -
 -              if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
 -                      mode &= ~S_ISGID;
 -              sd_iattr->ia_mode = sd->s_mode = mode;
 -      }
 +int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 +              size_t size, int flags)
 +{
 +      struct sysfs_dirent *sd = dentry->d_fsdata;
 +      struct sysfs_inode_attrs *iattrs;
 +      void *secdata;
 +      int error;
 +      u32 secdata_len = 0;
 +
 +      if (!sd)
 +              return -EINVAL;
 +      if (!sd->s_iattr)
 +              sd->s_iattr = sysfs_init_inode_attrs(sd);
 +      if (!sd->s_iattr)
 +              return -ENOMEM;
 +
 +      iattrs = sd->s_iattr;
 +
 +      if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) {
 +              const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
 +              error = security_inode_setsecurity(dentry->d_inode, suffix,
 +                                              value, size, flags);
 +              if (error)
 +                      goto out;
 +              error = security_inode_getsecctx(dentry->d_inode,
 +                                              &secdata, &secdata_len);
 +              if (error)
 +                      goto out;
 +              if (iattrs->ia_secdata)
 +                      security_release_secctx(iattrs->ia_secdata,
 +                                              iattrs->ia_secdata_len);
 +              iattrs->ia_secdata = secdata;
 +              iattrs->ia_secdata_len = secdata_len;
  
 +      } else
 +              return -EINVAL;
 +out:
        return error;
  }
  
@@@ -203,7 -147,6 +204,7 @@@ static int sysfs_count_nlink(struct sys
  static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
  {
        struct bin_attribute *bin_attr;
 +      struct sysfs_inode_attrs *iattrs;
  
        inode->i_private = sysfs_get(sd);
        inode->i_mapping->a_ops = &sysfs_aops;
        inode->i_ino = sd->s_ino;
        lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
  
 -      if (sd->s_iattr) {
 +      iattrs = sd->s_iattr;
 +      if (iattrs) {
                /* sysfs_dirent has non-default attributes
                 * get them for the new inode from persistent copy
                 * in sysfs_dirent
                 */
 -              set_inode_attr(inode, sd->s_iattr);
 +              set_inode_attr(inode, &iattrs->ia_iattr);
 +              if (iattrs->ia_secdata)
 +                      security_inode_notifysecctx(inode,
 +                                              iattrs->ia_secdata,
 +                                              iattrs->ia_secdata_len);
        } else
                set_default_inode_attr(inode, sd->s_mode);
  
 -
        /* initialize inode according to type */
        switch (sysfs_type(sd)) {
        case SYSFS_DIR: