71fe804b6d
This patch replaces the mempolicy mode, mode_flags, and nodemask in the shmem_sb_info struct with a struct mempolicy pointer, initialized to NULL. This removes dependency on the details of mempolicy from shmem.c and hugetlbfs inode.c and simplifies the interfaces. mpol_parse_str() in mempolicy.c is changed to return, via a pointer to a pointer arg, a struct mempolicy pointer on success. For MPOL_DEFAULT, the returned pointer is NULL. Further, mpol_parse_str() now takes a 'no_context' argument that causes the input nodemask to be stored in the w.user_nodemask of the created mempolicy for use when the mempolicy is installed in a tmpfs inode shared policy tree. At that time, any cpuset contextualization is applied to the original input nodemask. This preserves the previous behavior where the input nodemask was stored in the superblock. We can think of the returned mempolicy as "context free". Because mpol_parse_str() is now calling mpol_new(), we can remove from mpol_to_str() the semantic checks that mpol_new() already performs. Add 'no_context' parameter to mpol_to_str() to specify that it should format the nodemask in w.user_nodemask for 'bind' and 'interleave' policies. Change mpol_shared_policy_init() to take a pointer to a "context free" struct mempolicy and to create a new, "contextualized" mempolicy using the mode, mode_flags and user_nodemask from the input mempolicy. Note: we know that the mempolicy passed to mpol_to_str() or mpol_shared_policy_init() from a tmpfs superblock is "context free". This is currently the only instance thereof. However, if we found more uses for this concept, and introduced any ambiguity as to whether a mempolicy was context free or not, we could add another internal mode flag to identify context free mempolicies. Then, we could remove the 'no_context' argument from mpol_to_str(). Added shmem_get_sbmpol() to return a reference counted superblock mempolicy, if one exists, to pass to mpol_shared_policy_init(). We must add the reference under the sb stat_lock to prevent races with replacement of the mpol by remount. This reference is removed in mpol_shared_policy_init(). [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: another build fix] [akpm@linux-foundation.org: yet another build fix] Signed-off-by: Lee Schermerhorn <lee.schermerhorn@hp.com> Cc: Christoph Lameter <clameter@sgi.com> Cc: David Rientjes <rientjes@google.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
65 lines
2 KiB
C
65 lines
2 KiB
C
#ifndef __SHMEM_FS_H
|
|
#define __SHMEM_FS_H
|
|
|
|
#include <linux/swap.h>
|
|
#include <linux/mempolicy.h>
|
|
|
|
/* inode in-kernel data */
|
|
|
|
#define SHMEM_NR_DIRECT 16
|
|
|
|
struct shmem_inode_info {
|
|
spinlock_t lock;
|
|
unsigned long flags;
|
|
unsigned long alloced; /* data pages alloced to file */
|
|
unsigned long swapped; /* subtotal assigned to swap */
|
|
unsigned long next_index; /* highest alloced index + 1 */
|
|
struct shared_policy policy; /* NUMA memory alloc policy */
|
|
struct page *i_indirect; /* top indirect blocks page */
|
|
swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* first blocks */
|
|
struct list_head swaplist; /* chain of maybes on swap */
|
|
struct inode vfs_inode;
|
|
#ifdef CONFIG_TMPFS_POSIX_ACL
|
|
struct posix_acl *i_acl;
|
|
struct posix_acl *i_default_acl;
|
|
#endif
|
|
};
|
|
|
|
struct shmem_sb_info {
|
|
unsigned long max_blocks; /* How many blocks are allowed */
|
|
unsigned long free_blocks; /* How many are left for allocation */
|
|
unsigned long max_inodes; /* How many inodes are allowed */
|
|
unsigned long free_inodes; /* How many are left for allocation */
|
|
spinlock_t stat_lock; /* Serialize shmem_sb_info changes */
|
|
uid_t uid; /* Mount uid for root directory */
|
|
gid_t gid; /* Mount gid for root directory */
|
|
mode_t mode; /* Mount mode for root directory */
|
|
struct mempolicy *mpol; /* default memory policy for mappings */
|
|
};
|
|
|
|
static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
|
|
{
|
|
return container_of(inode, struct shmem_inode_info, vfs_inode);
|
|
}
|
|
|
|
#ifdef CONFIG_TMPFS_POSIX_ACL
|
|
int shmem_permission(struct inode *, int, struct nameidata *);
|
|
int shmem_acl_init(struct inode *, struct inode *);
|
|
void shmem_acl_destroy_inode(struct inode *);
|
|
|
|
extern struct xattr_handler shmem_xattr_acl_access_handler;
|
|
extern struct xattr_handler shmem_xattr_acl_default_handler;
|
|
|
|
extern struct generic_acl_operations shmem_acl_ops;
|
|
|
|
#else
|
|
static inline int shmem_acl_init(struct inode *inode, struct inode *dir)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline void shmem_acl_destroy_inode(struct inode *inode)
|
|
{
|
|
}
|
|
#endif /* CONFIG_TMPFS_POSIX_ACL */
|
|
|
|
#endif
|