Skip to content

Commit

Permalink
Merge tag 'xfs-for-linus-v3.12-rc1' of git://oss.sgi.com/xfs/xfs
Browse files Browse the repository at this point in the history
Pull xfs updates from Ben Myers:
 "For 3.12-rc1 there are a number of bugfixes in addition to work to
  ease usage of shared code between libxfs and the kernel, the rest of
  the work to enable project and group quotas to be used simultaneously,
  performance optimisations in the log and the CIL, directory entry file
  type support, fixes for log space reservations, some spelling/grammar
  cleanups, and the addition of user namespace support.

   - introduce readahead to log recovery
   - add directory entry file type support
   - fix a number of spelling errors in comments
   - introduce new Q_XGETQSTATV quotactl for project quotas
   - add USER_NS support
   - log space reservation rework
   - CIL optimisations
  - kernel/userspace libxfs rework"

* tag 'xfs-for-linus-v3.12-rc1' of git://oss.sgi.com/xfs/xfs: (112 commits)
  xfs: XFS_MOUNT_QUOTA_ALL needed by userspace
  xfs: dtype changed xfs_dir2_sfe_put_ino to xfs_dir3_sfe_put_ino
  Fix wrong flag ASSERT in xfs_attr_shortform_getvalue
  xfs: finish removing IOP_* macros.
  xfs: inode log reservations are too small
  xfs: check correct status variable for xfs_inobt_get_rec() call
  xfs: inode buffers may not be valid during recovery readahead
  xfs: check LSN ordering for v5 superblocks during recovery
  xfs: btree block LSN escaping to disk uninitialised
  XFS: Assertion failed: first <= last && last < BBTOB(bp->b_length), file: fs/xfs/xfs_trans_buf.c, line: 568
  xfs: fix bad dquot buffer size in log recovery readahead
  xfs: don't account buffer cancellation during log recovery readahead
  xfs: check for underflow in xfs_iformat_fork()
  xfs: xfs_dir3_sfe_put_ino can be static
  xfs: introduce object readahead to log recovery
  xfs: Simplify xfs_ail_min() with list_first_entry_or_null()
  xfs: Register hotcpu notifier after initialization
  xfs: add xfs sb v4 support for dirent filetype field
  xfs: Add write support for dirent filetype field
  xfs: Add read-only support for dirent filetype field
  ...
  • Loading branch information
torvalds committed Sep 9, 2013
2 parents 45150c4 + 1d03c6f commit 300893b
Show file tree
Hide file tree
Showing 116 changed files with 13,653 additions and 11,951 deletions.
8 changes: 6 additions & 2 deletions arch/powerpc/platforms/cell/spufs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,12 +620,16 @@ spufs_parse_options(struct super_block *sb, char *options, struct inode *root)
case Opt_uid:
if (match_int(&args[0], &option))
return 0;
root->i_uid = option;
root->i_uid = make_kuid(current_user_ns(), option);
if (!uid_valid(root->i_uid))
return 0;
break;
case Opt_gid:
if (match_int(&args[0], &option))
return 0;
root->i_gid = option;
root->i_gid = make_kgid(current_user_ns(), option);
if (!gid_valid(root->i_gid))
return 0;
break;
case Opt_mode:
if (match_octal(&args[0], &option))
Expand Down
29 changes: 29 additions & 0 deletions fs/quota/quota.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
case Q_SYNC:
case Q_GETINFO:
case Q_XGETQSTAT:
case Q_XGETQSTATV:
case Q_XQUOTASYNC:
break;
/* allow to query information for dquots we "own" */
Expand Down Expand Up @@ -217,6 +218,31 @@ static int quota_getxstate(struct super_block *sb, void __user *addr)
return ret;
}

static int quota_getxstatev(struct super_block *sb, void __user *addr)
{
struct fs_quota_statv fqs;
int ret;

if (!sb->s_qcop->get_xstatev)
return -ENOSYS;

memset(&fqs, 0, sizeof(fqs));
if (copy_from_user(&fqs, addr, 1)) /* Just read qs_version */
return -EFAULT;

/* If this kernel doesn't support user specified version, fail */
switch (fqs.qs_version) {
case FS_QSTATV_VERSION1:
break;
default:
return -EINVAL;
}
ret = sb->s_qcop->get_xstatev(sb, &fqs);
if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
return -EFAULT;
return ret;
}

static int quota_setxquota(struct super_block *sb, int type, qid_t id,
void __user *addr)
{
Expand Down Expand Up @@ -293,6 +319,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
return quota_setxstate(sb, cmd, addr);
case Q_XGETQSTAT:
return quota_getxstate(sb, addr);
case Q_XGETQSTATV:
return quota_getxstatev(sb, addr);
case Q_XSETQLIM:
return quota_setxquota(sb, type, id, addr);
case Q_XGETQUOTA:
Expand All @@ -317,6 +345,7 @@ static int quotactl_cmd_write(int cmd)
case Q_GETINFO:
case Q_SYNC:
case Q_XGETQSTAT:
case Q_XGETQSTATV:
case Q_XGETQUOTA:
case Q_XQUOTASYNC:
return 0;
Expand Down
20 changes: 13 additions & 7 deletions fs/xfs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ xfs-y += xfs_trace.o

# highlevel code
xfs-y += xfs_aops.o \
xfs_attr_inactive.o \
xfs_attr_list.o \
xfs_bit.o \
xfs_bmap_util.o \
xfs_buf.o \
xfs_dfrag.o \
xfs_dir2_readdir.o \
xfs_discard.o \
xfs_error.o \
xfs_export.o \
Expand All @@ -44,11 +47,11 @@ xfs-y += xfs_aops.o \
xfs_iops.o \
xfs_itable.o \
xfs_message.o \
xfs_mount.o \
xfs_mru_cache.o \
xfs_rename.o \
xfs_super.o \
xfs_utils.o \
xfs_vnodeops.o \
xfs_symlink.o \
xfs_trans.o \
xfs_xattr.o \
kmem.o \
uuid.o
Expand All @@ -73,10 +76,13 @@ xfs-y += xfs_alloc.o \
xfs_ialloc_btree.o \
xfs_icreate_item.o \
xfs_inode.o \
xfs_inode_fork.o \
xfs_inode_buf.o \
xfs_log_recover.o \
xfs_mount.o \
xfs_symlink.o \
xfs_trans.o
xfs_log_rlimit.o \
xfs_sb.o \
xfs_symlink_remote.o \
xfs_trans_resv.o

# low-level transaction/log code
xfs-y += xfs_log.o \
Expand Down
24 changes: 19 additions & 5 deletions fs/xfs/xfs_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
#include "xfs_log_format.h"
#include "xfs_trans_resv.h"
#include "xfs_acl.h"
#include "xfs_attr.h"
#include "xfs_bmap_btree.h"
#include "xfs_inode.h"
#include "xfs_vnodeops.h"
#include "xfs_ag.h"
#include "xfs_sb.h"
#include "xfs_mount.h"
#include "xfs_trace.h"
Expand Down Expand Up @@ -68,14 +70,15 @@ xfs_acl_from_disk(

switch (acl_e->e_tag) {
case ACL_USER:
acl_e->e_uid = xfs_uid_to_kuid(be32_to_cpu(ace->ae_id));
break;
case ACL_GROUP:
acl_e->e_id = be32_to_cpu(ace->ae_id);
acl_e->e_gid = xfs_gid_to_kgid(be32_to_cpu(ace->ae_id));
break;
case ACL_USER_OBJ:
case ACL_GROUP_OBJ:
case ACL_MASK:
case ACL_OTHER:
acl_e->e_id = ACL_UNDEFINED_ID;
break;
default:
goto fail;
Expand All @@ -101,7 +104,18 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl)
acl_e = &acl->a_entries[i];

ace->ae_tag = cpu_to_be32(acl_e->e_tag);
ace->ae_id = cpu_to_be32(acl_e->e_id);
switch (acl_e->e_tag) {
case ACL_USER:
ace->ae_id = cpu_to_be32(xfs_kuid_to_uid(acl_e->e_uid));
break;
case ACL_GROUP:
ace->ae_id = cpu_to_be32(xfs_kgid_to_gid(acl_e->e_gid));
break;
default:
ace->ae_id = cpu_to_be32(ACL_UNDEFINED_ID);
break;
}

ace->ae_perm = cpu_to_be16(acl_e->e_perm);
}
}
Expand Down Expand Up @@ -360,7 +374,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
return -EINVAL;
if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
return value ? -EACCES : 0;
if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER))
if (!inode_owner_or_capable(inode))
return -EPERM;

if (!value)
Expand Down
53 changes: 0 additions & 53 deletions fs/xfs/xfs_ag.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,59 +226,6 @@ typedef struct xfs_agfl {
__be32 agfl_bno[]; /* actually XFS_AGFL_SIZE(mp) */
} xfs_agfl_t;

/*
* Per-ag incore structure, copies of information in agf and agi,
* to improve the performance of allocation group selection.
*/
#define XFS_PAGB_NUM_SLOTS 128

typedef struct xfs_perag {
struct xfs_mount *pag_mount; /* owner filesystem */
xfs_agnumber_t pag_agno; /* AG this structure belongs to */
atomic_t pag_ref; /* perag reference count */
char pagf_init; /* this agf's entry is initialized */
char pagi_init; /* this agi's entry is initialized */
char pagf_metadata; /* the agf is preferred to be metadata */
char pagi_inodeok; /* The agi is ok for inodes */
__uint8_t pagf_levels[XFS_BTNUM_AGF];
/* # of levels in bno & cnt btree */
__uint32_t pagf_flcount; /* count of blocks in freelist */
xfs_extlen_t pagf_freeblks; /* total free blocks */
xfs_extlen_t pagf_longest; /* longest free space */
__uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */
xfs_agino_t pagi_freecount; /* number of free inodes */
xfs_agino_t pagi_count; /* number of allocated inodes */

/*
* Inode allocation search lookup optimisation.
* If the pagino matches, the search for new inodes
* doesn't need to search the near ones again straight away
*/
xfs_agino_t pagl_pagino;
xfs_agino_t pagl_leftrec;
xfs_agino_t pagl_rightrec;
#ifdef __KERNEL__
spinlock_t pagb_lock; /* lock for pagb_tree */
struct rb_root pagb_tree; /* ordered tree of busy extents */

atomic_t pagf_fstrms; /* # of filestreams active in this AG */

spinlock_t pag_ici_lock; /* incore inode cache lock */
struct radix_tree_root pag_ici_root; /* incore inode cache root */
int pag_ici_reclaimable; /* reclaimable inodes */
struct mutex pag_ici_reclaim_lock; /* serialisation point */
unsigned long pag_ici_reclaim_cursor; /* reclaim restart point */

/* buffer cache index */
spinlock_t pag_buf_lock; /* lock for pag_buf_tree */
struct rb_root pag_buf_tree; /* ordered tree of active buffers */

/* for rcu-safe freeing */
struct rcu_head rcu_head;
#endif
int pagb_count; /* pagb slots in use */
} xfs_perag_t;

/*
* tags for inode radix tree
*/
Expand Down
6 changes: 3 additions & 3 deletions fs/xfs/xfs_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ xfs_alloc_ag_vextent_near(
xfs_agblock_t ltnew; /* useful start bno of left side */
xfs_extlen_t rlen; /* length of returned extent */
int forced = 0;
#if defined(DEBUG) && defined(__KERNEL__)
#ifdef DEBUG
/*
* Randomly don't execute the first algorithm.
*/
Expand Down Expand Up @@ -938,8 +938,8 @@ xfs_alloc_ag_vextent_near(
xfs_extlen_t blen=0;
xfs_agblock_t bnew=0;

#if defined(DEBUG) && defined(__KERNEL__)
if (!dofirst)
#ifdef DEBUG
if (dofirst)
break;
#endif
/*
Expand Down
23 changes: 18 additions & 5 deletions fs/xfs/xfs_aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
#include "xfs_alloc.h"
#include "xfs_error.h"
#include "xfs_iomap.h"
#include "xfs_vnodeops.h"
#include "xfs_trace.h"
#include "xfs_bmap.h"
#include "xfs_bmap_util.h"
#include <linux/aio.h>
#include <linux/gfp.h>
#include <linux/mpage.h>
Expand Down Expand Up @@ -108,7 +108,7 @@ xfs_setfilesize_trans_alloc(

tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);

error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0);
if (error) {
xfs_trans_cancel(tp, 0);
return error;
Expand Down Expand Up @@ -440,7 +440,7 @@ xfs_start_page_writeback(
end_page_writeback(page);
}

static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh)
static inline int xfs_bio_add_buffer(struct bio *bio, struct buffer_head *bh)
{
return bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh));
}
Expand Down Expand Up @@ -514,7 +514,7 @@ xfs_submit_ioend(
goto retry;
}

if (bio_add_buffer(bio, bh) != bh->b_size) {
if (xfs_bio_add_buffer(bio, bh) != bh->b_size) {
xfs_submit_ioend_bio(wbc, ioend, bio);
goto retry;
}
Expand Down Expand Up @@ -1498,13 +1498,26 @@ xfs_vm_write_failed(
loff_t pos,
unsigned len)
{
loff_t block_offset = pos & PAGE_MASK;
loff_t block_offset;
loff_t block_start;
loff_t block_end;
loff_t from = pos & (PAGE_CACHE_SIZE - 1);
loff_t to = from + len;
struct buffer_head *bh, *head;

/*
* The request pos offset might be 32 or 64 bit, this is all fine
* on 64-bit platform. However, for 64-bit pos request on 32-bit
* platform, the high 32-bit will be masked off if we evaluate the
* block_offset via (pos & PAGE_MASK) because the PAGE_MASK is
* 0xfffff000 as an unsigned long, hence the result is incorrect
* which could cause the following ASSERT failed in most cases.
* In order to avoid this, we can evaluate the block_offset of the
* start of the page by using shifts rather than masks the mismatch
* problem.
*/
block_offset = (pos >> PAGE_CACHE_SHIFT) << PAGE_CACHE_SHIFT;

ASSERT(block_offset + from == pos);

head = page_buffers(page);
Expand Down
Loading

0 comments on commit 300893b

Please sign in to comment.