mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 06:31:52 +00:00
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2: ocfs2/trivial: Use le16_to_cpu for a disk value in xattr.c ocfs2/trivial: Use proper mask for 2 places in hearbeat.c Ocfs2: Let ocfs2 support fiemap for symlink and fast symlink. Ocfs2: Should ocfs2 support fiemap for S_IFDIR inode? ocfs2: Use FIEMAP_EXTENT_SHARED fiemap: Add new extent flag FIEMAP_EXTENT_SHARED ocfs2: replace u8 by __u8 in ocfs2_fs.h ocfs2: explicit declare uninitialized var in user_cluster_connect() ocfs2-devel: remove redundant OCFS2_MOUNT_POSIX_ACL check in ocfs2_get_acl_nolock() ocfs2: return -EAGAIN instead of EAGAIN in dlm ocfs2/cluster: Make fence method configurable - v2 ocfs2: Set MS_POSIXACL on remount ocfs2: Make acl use the default ocfs2: Always include ACL support
This commit is contained in:
commit
45e62974fb
@ -6,6 +6,7 @@ config OCFS2_FS
|
||||
select CRC32
|
||||
select QUOTA
|
||||
select QUOTA_TREE
|
||||
select FS_POSIX_ACL
|
||||
help
|
||||
OCFS2 is a general purpose extent based shared disk cluster file
|
||||
system with many similarities to ext3. It supports 64 bit inode
|
||||
@ -74,12 +75,3 @@ config OCFS2_DEBUG_FS
|
||||
This option will enable expensive consistency checks. Enable
|
||||
this option for debugging only as it is likely to decrease
|
||||
performance of the filesystem.
|
||||
|
||||
config OCFS2_FS_POSIX_ACL
|
||||
bool "OCFS2 POSIX Access Control Lists"
|
||||
depends on OCFS2_FS
|
||||
select FS_POSIX_ACL
|
||||
default n
|
||||
help
|
||||
Posix Access Control Lists (ACLs) support permissions for users and
|
||||
groups beyond the owner/group/world scheme.
|
||||
|
@ -39,11 +39,8 @@ ocfs2-objs := \
|
||||
ver.o \
|
||||
quota_local.o \
|
||||
quota_global.o \
|
||||
xattr.o
|
||||
|
||||
ifeq ($(CONFIG_OCFS2_FS_POSIX_ACL),y)
|
||||
ocfs2-objs += acl.o
|
||||
endif
|
||||
xattr.o \
|
||||
acl.o
|
||||
|
||||
ocfs2_stackglue-objs := stackglue.o
|
||||
ocfs2_stack_o2cb-objs := stack_o2cb.o
|
||||
|
@ -98,15 +98,11 @@ static struct posix_acl *ocfs2_get_acl_nolock(struct inode *inode,
|
||||
int type,
|
||||
struct buffer_head *di_bh)
|
||||
{
|
||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||
int name_index;
|
||||
char *value = NULL;
|
||||
struct posix_acl *acl;
|
||||
int retval;
|
||||
|
||||
if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
|
||||
return NULL;
|
||||
|
||||
switch (type) {
|
||||
case ACL_TYPE_ACCESS:
|
||||
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
|
||||
|
@ -26,8 +26,6 @@ struct ocfs2_acl_entry {
|
||||
__le32 e_id;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
||||
|
||||
extern int ocfs2_check_acl(struct inode *, int);
|
||||
extern int ocfs2_acl_chmod(struct inode *);
|
||||
extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *,
|
||||
@ -35,24 +33,4 @@ extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *,
|
||||
struct ocfs2_alloc_context *,
|
||||
struct ocfs2_alloc_context *);
|
||||
|
||||
#else /* CONFIG_OCFS2_FS_POSIX_ACL*/
|
||||
|
||||
#define ocfs2_check_acl NULL
|
||||
static inline int ocfs2_acl_chmod(struct inode *inode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int ocfs2_init_acl(handle_t *handle,
|
||||
struct inode *inode,
|
||||
struct inode *dir,
|
||||
struct buffer_head *di_bh,
|
||||
struct buffer_head *dir_bh,
|
||||
struct ocfs2_alloc_context *meta_ac,
|
||||
struct ocfs2_alloc_context *data_ac)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_OCFS2_FS_POSIX_ACL*/
|
||||
|
||||
#endif /* OCFS2_ACL_H */
|
||||
|
@ -176,7 +176,8 @@ static void o2hb_write_timeout(struct work_struct *work)
|
||||
|
||||
static void o2hb_arm_write_timeout(struct o2hb_region *reg)
|
||||
{
|
||||
mlog(0, "Queue write timeout for %u ms\n", O2HB_MAX_WRITE_TIMEOUT_MS);
|
||||
mlog(ML_HEARTBEAT, "Queue write timeout for %u ms\n",
|
||||
O2HB_MAX_WRITE_TIMEOUT_MS);
|
||||
|
||||
cancel_delayed_work(®->hr_write_timeout_work);
|
||||
reg->hr_last_timeout_start = jiffies;
|
||||
@ -874,7 +875,8 @@ static int o2hb_thread(void *data)
|
||||
do_gettimeofday(&after_hb);
|
||||
elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb);
|
||||
|
||||
mlog(0, "start = %lu.%lu, end = %lu.%lu, msec = %u\n",
|
||||
mlog(ML_HEARTBEAT,
|
||||
"start = %lu.%lu, end = %lu.%lu, msec = %u\n",
|
||||
before_hb.tv_sec, (unsigned long) before_hb.tv_usec,
|
||||
after_hb.tv_sec, (unsigned long) after_hb.tv_usec,
|
||||
elapsed_msec);
|
||||
|
@ -35,6 +35,10 @@
|
||||
* cluster references throughout where nodes are looked up */
|
||||
struct o2nm_cluster *o2nm_single_cluster = NULL;
|
||||
|
||||
char *o2nm_fence_method_desc[O2NM_FENCE_METHODS] = {
|
||||
"reset", /* O2NM_FENCE_RESET */
|
||||
"panic", /* O2NM_FENCE_PANIC */
|
||||
};
|
||||
|
||||
struct o2nm_node *o2nm_get_node_by_num(u8 node_num)
|
||||
{
|
||||
@ -579,6 +583,43 @@ static ssize_t o2nm_cluster_attr_reconnect_delay_ms_write(
|
||||
return o2nm_cluster_attr_write(page, count,
|
||||
&cluster->cl_reconnect_delay_ms);
|
||||
}
|
||||
|
||||
static ssize_t o2nm_cluster_attr_fence_method_read(
|
||||
struct o2nm_cluster *cluster, char *page)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
|
||||
if (cluster)
|
||||
ret = sprintf(page, "%s\n",
|
||||
o2nm_fence_method_desc[cluster->cl_fence_method]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t o2nm_cluster_attr_fence_method_write(
|
||||
struct o2nm_cluster *cluster, const char *page, size_t count)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (page[count - 1] != '\n')
|
||||
goto bail;
|
||||
|
||||
for (i = 0; i < O2NM_FENCE_METHODS; ++i) {
|
||||
if (count != strlen(o2nm_fence_method_desc[i]) + 1)
|
||||
continue;
|
||||
if (strncasecmp(page, o2nm_fence_method_desc[i], count - 1))
|
||||
continue;
|
||||
if (cluster->cl_fence_method != i) {
|
||||
printk(KERN_INFO "ocfs2: Changing fence method to %s\n",
|
||||
o2nm_fence_method_desc[i]);
|
||||
cluster->cl_fence_method = i;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bail:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = {
|
||||
.attr = { .ca_owner = THIS_MODULE,
|
||||
.ca_name = "idle_timeout_ms",
|
||||
@ -603,10 +644,19 @@ static struct o2nm_cluster_attribute o2nm_cluster_attr_reconnect_delay_ms = {
|
||||
.store = o2nm_cluster_attr_reconnect_delay_ms_write,
|
||||
};
|
||||
|
||||
static struct o2nm_cluster_attribute o2nm_cluster_attr_fence_method = {
|
||||
.attr = { .ca_owner = THIS_MODULE,
|
||||
.ca_name = "fence_method",
|
||||
.ca_mode = S_IRUGO | S_IWUSR },
|
||||
.show = o2nm_cluster_attr_fence_method_read,
|
||||
.store = o2nm_cluster_attr_fence_method_write,
|
||||
};
|
||||
|
||||
static struct configfs_attribute *o2nm_cluster_attrs[] = {
|
||||
&o2nm_cluster_attr_idle_timeout_ms.attr,
|
||||
&o2nm_cluster_attr_keepalive_delay_ms.attr,
|
||||
&o2nm_cluster_attr_reconnect_delay_ms.attr,
|
||||
&o2nm_cluster_attr_fence_method.attr,
|
||||
NULL,
|
||||
};
|
||||
static ssize_t o2nm_cluster_show(struct config_item *item,
|
||||
@ -778,6 +828,7 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g
|
||||
cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT;
|
||||
cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT;
|
||||
cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT;
|
||||
cluster->cl_fence_method = O2NM_FENCE_RESET;
|
||||
|
||||
ret = &cluster->cl_group;
|
||||
o2nm_single_cluster = cluster;
|
||||
|
@ -33,6 +33,12 @@
|
||||
#include <linux/configfs.h>
|
||||
#include <linux/rbtree.h>
|
||||
|
||||
enum o2nm_fence_method {
|
||||
O2NM_FENCE_RESET = 0,
|
||||
O2NM_FENCE_PANIC,
|
||||
O2NM_FENCE_METHODS, /* Number of fence methods */
|
||||
};
|
||||
|
||||
struct o2nm_node {
|
||||
spinlock_t nd_lock;
|
||||
struct config_item nd_item;
|
||||
@ -58,6 +64,7 @@ struct o2nm_cluster {
|
||||
unsigned int cl_idle_timeout_ms;
|
||||
unsigned int cl_keepalive_delay_ms;
|
||||
unsigned int cl_reconnect_delay_ms;
|
||||
enum o2nm_fence_method cl_fence_method;
|
||||
|
||||
/* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */
|
||||
unsigned long cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
|
||||
|
@ -74,8 +74,20 @@ static void o2quo_fence_self(void)
|
||||
* threads can still schedule, etc, etc */
|
||||
o2hb_stop_all_regions();
|
||||
|
||||
printk("ocfs2 is very sorry to be fencing this system by restarting\n");
|
||||
switch (o2nm_single_cluster->cl_fence_method) {
|
||||
case O2NM_FENCE_PANIC:
|
||||
panic("*** ocfs2 is very sorry to be fencing this system by "
|
||||
"panicing ***\n");
|
||||
break;
|
||||
default:
|
||||
WARN_ON(o2nm_single_cluster->cl_fence_method >=
|
||||
O2NM_FENCE_METHODS);
|
||||
case O2NM_FENCE_RESET:
|
||||
printk(KERN_ERR "*** ocfs2 is very sorry to be fencing this "
|
||||
"system by restarting ***\n");
|
||||
emergency_restart();
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
/* Indicate that a timeout occured on a hearbeat region write. The
|
||||
|
@ -2589,6 +2589,14 @@ retry:
|
||||
"begin reco msg (%d)\n", dlm->name, nodenum, ret);
|
||||
ret = 0;
|
||||
}
|
||||
if (ret == -EAGAIN) {
|
||||
mlog(0, "%s: trying to start recovery of node "
|
||||
"%u, but node %u is waiting for last recovery "
|
||||
"to complete, backoff for a bit\n", dlm->name,
|
||||
dead_node, nodenum);
|
||||
msleep(100);
|
||||
goto retry;
|
||||
}
|
||||
if (ret < 0) {
|
||||
struct dlm_lock_resource *res;
|
||||
/* this is now a serious problem, possibly ENOMEM
|
||||
@ -2608,14 +2616,6 @@ retry:
|
||||
* another ENOMEM */
|
||||
msleep(100);
|
||||
goto retry;
|
||||
} else if (ret == EAGAIN) {
|
||||
mlog(0, "%s: trying to start recovery of node "
|
||||
"%u, but node %u is waiting for last recovery "
|
||||
"to complete, backoff for a bit\n", dlm->name,
|
||||
dead_node, nodenum);
|
||||
/* TODO Look into replacing msleep with cond_resched() */
|
||||
msleep(100);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2639,7 +2639,7 @@ int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data,
|
||||
dlm->name, br->node_idx, br->dead_node,
|
||||
dlm->reco.dead_node, dlm->reco.new_master);
|
||||
spin_unlock(&dlm->spinlock);
|
||||
return EAGAIN;
|
||||
return -EAGAIN;
|
||||
}
|
||||
spin_unlock(&dlm->spinlock);
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "extent_map.h"
|
||||
#include "inode.h"
|
||||
#include "super.h"
|
||||
#include "symlink.h"
|
||||
|
||||
#include "buffer_head_io.h"
|
||||
|
||||
@ -703,6 +704,12 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The ocfs2_fiemap_inline() may be a little bit misleading, since
|
||||
* it not only handles the fiemap for inlined files, but also deals
|
||||
* with the fast symlink, cause they have no difference for extent
|
||||
* mapping per se.
|
||||
*/
|
||||
static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh,
|
||||
struct fiemap_extent_info *fieinfo,
|
||||
u64 map_start)
|
||||
@ -715,11 +722,18 @@ static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh,
|
||||
struct ocfs2_inode_info *oi = OCFS2_I(inode);
|
||||
|
||||
di = (struct ocfs2_dinode *)di_bh->b_data;
|
||||
if (ocfs2_inode_is_fast_symlink(inode))
|
||||
id_count = ocfs2_fast_symlink_chars(inode->i_sb);
|
||||
else
|
||||
id_count = le16_to_cpu(di->id2.i_data.id_count);
|
||||
|
||||
if (map_start < id_count) {
|
||||
phys = oi->ip_blkno << inode->i_sb->s_blocksize_bits;
|
||||
phys += offsetof(struct ocfs2_dinode, id2.i_data.id_data);
|
||||
if (ocfs2_inode_is_fast_symlink(inode))
|
||||
phys += offsetof(struct ocfs2_dinode, id2.i_symlink);
|
||||
else
|
||||
phys += offsetof(struct ocfs2_dinode,
|
||||
id2.i_data.id_data);
|
||||
|
||||
ret = fiemap_fill_next_extent(fieinfo, 0, phys, id_count,
|
||||
flags);
|
||||
@ -756,9 +770,10 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||
down_read(&OCFS2_I(inode)->ip_alloc_sem);
|
||||
|
||||
/*
|
||||
* Handle inline-data separately.
|
||||
* Handle inline-data and fast symlink separately.
|
||||
*/
|
||||
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
|
||||
if ((OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) ||
|
||||
ocfs2_inode_is_fast_symlink(inode)) {
|
||||
ret = ocfs2_fiemap_inline(inode, di_bh, fieinfo, map_start);
|
||||
goto out_unlock;
|
||||
}
|
||||
@ -786,6 +801,8 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||
fe_flags = 0;
|
||||
if (rec.e_flags & OCFS2_EXT_UNWRITTEN)
|
||||
fe_flags |= FIEMAP_EXTENT_UNWRITTEN;
|
||||
if (rec.e_flags & OCFS2_EXT_REFCOUNTED)
|
||||
fe_flags |= FIEMAP_EXTENT_SHARED;
|
||||
if (is_last)
|
||||
fe_flags |= FIEMAP_EXTENT_LAST;
|
||||
len_bytes = (u64)le16_to_cpu(rec.e_leaf_clusters) << osb->s_clustersize_bits;
|
||||
|
@ -2329,4 +2329,5 @@ const struct inode_operations ocfs2_dir_iops = {
|
||||
.getxattr = generic_getxattr,
|
||||
.listxattr = ocfs2_listxattr,
|
||||
.removexattr = generic_removexattr,
|
||||
.fiemap = ocfs2_fiemap,
|
||||
};
|
||||
|
@ -245,9 +245,11 @@ enum ocfs2_mount_options
|
||||
OCFS2_MOUNT_LOCALFLOCKS = 1 << 5, /* No cluster aware user file locks */
|
||||
OCFS2_MOUNT_NOUSERXATTR = 1 << 6, /* No user xattr */
|
||||
OCFS2_MOUNT_INODE64 = 1 << 7, /* Allow inode numbers > 2^32 */
|
||||
OCFS2_MOUNT_POSIX_ACL = 1 << 8, /* POSIX access control lists */
|
||||
OCFS2_MOUNT_USRQUOTA = 1 << 9, /* We support user quotas */
|
||||
OCFS2_MOUNT_GRPQUOTA = 1 << 10, /* We support group quotas */
|
||||
OCFS2_MOUNT_POSIX_ACL = 1 << 8, /* Force POSIX access control lists */
|
||||
OCFS2_MOUNT_NO_POSIX_ACL = 1 << 9, /* Disable POSIX access
|
||||
control lists */
|
||||
OCFS2_MOUNT_USRQUOTA = 1 << 10, /* We support user quotas */
|
||||
OCFS2_MOUNT_GRPQUOTA = 1 << 11, /* We support group quotas */
|
||||
};
|
||||
|
||||
#define OCFS2_OSB_SOFT_RO 0x0001
|
||||
|
@ -1202,7 +1202,7 @@ struct ocfs2_local_disk_dqinfo {
|
||||
/* Header of one chunk of a quota file */
|
||||
struct ocfs2_local_disk_chunk {
|
||||
__le32 dqc_free; /* Number of free entries in the bitmap */
|
||||
u8 dqc_bitmap[0]; /* Bitmap of entries in the corresponding
|
||||
__u8 dqc_bitmap[0]; /* Bitmap of entries in the corresponding
|
||||
* chunk of quota file */
|
||||
};
|
||||
|
||||
|
@ -814,7 +814,7 @@ static int fs_protocol_compare(struct ocfs2_protocol_version *existing,
|
||||
static int user_cluster_connect(struct ocfs2_cluster_connection *conn)
|
||||
{
|
||||
dlm_lockspace_t *fsdlm;
|
||||
struct ocfs2_live_connection *control;
|
||||
struct ocfs2_live_connection *uninitialized_var(control);
|
||||
int rc = 0;
|
||||
|
||||
BUG_ON(conn == NULL);
|
||||
|
@ -100,6 +100,8 @@ struct mount_options
|
||||
static int ocfs2_parse_options(struct super_block *sb, char *options,
|
||||
struct mount_options *mopt,
|
||||
int is_remount);
|
||||
static int ocfs2_check_set_options(struct super_block *sb,
|
||||
struct mount_options *options);
|
||||
static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt);
|
||||
static void ocfs2_put_super(struct super_block *sb);
|
||||
static int ocfs2_mount_volume(struct super_block *sb);
|
||||
@ -600,7 +602,8 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
|
||||
|
||||
lock_kernel();
|
||||
|
||||
if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) {
|
||||
if (!ocfs2_parse_options(sb, data, &parsed_options, 1) ||
|
||||
!ocfs2_check_set_options(sb, &parsed_options)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@ -691,8 +694,6 @@ unlock_osb:
|
||||
if (!ret) {
|
||||
/* Only save off the new mount options in case of a successful
|
||||
* remount. */
|
||||
if (!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_XATTR))
|
||||
parsed_options.mount_opt &= ~OCFS2_MOUNT_POSIX_ACL;
|
||||
osb->s_mount_opt = parsed_options.mount_opt;
|
||||
osb->s_atime_quantum = parsed_options.atime_quantum;
|
||||
osb->preferred_slot = parsed_options.slot;
|
||||
@ -701,6 +702,10 @@ unlock_osb:
|
||||
|
||||
if (!ocfs2_is_hard_readonly(osb))
|
||||
ocfs2_set_journal_params(osb);
|
||||
|
||||
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
|
||||
((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) ?
|
||||
MS_POSIXACL : 0);
|
||||
}
|
||||
out:
|
||||
unlock_kernel();
|
||||
@ -1011,31 +1016,16 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
|
||||
brelse(bh);
|
||||
bh = NULL;
|
||||
|
||||
if (!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_XATTR))
|
||||
parsed_options.mount_opt &= ~OCFS2_MOUNT_POSIX_ACL;
|
||||
|
||||
if (!ocfs2_check_set_options(sb, &parsed_options)) {
|
||||
status = -EINVAL;
|
||||
goto read_super_error;
|
||||
}
|
||||
osb->s_mount_opt = parsed_options.mount_opt;
|
||||
osb->s_atime_quantum = parsed_options.atime_quantum;
|
||||
osb->preferred_slot = parsed_options.slot;
|
||||
osb->osb_commit_interval = parsed_options.commit_interval;
|
||||
osb->local_alloc_default_bits = ocfs2_megabytes_to_clusters(sb, parsed_options.localalloc_opt);
|
||||
osb->local_alloc_bits = osb->local_alloc_default_bits;
|
||||
if (osb->s_mount_opt & OCFS2_MOUNT_USRQUOTA &&
|
||||
!OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
||||
OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) {
|
||||
status = -EINVAL;
|
||||
mlog(ML_ERROR, "User quotas were requested, but this "
|
||||
"filesystem does not have the feature enabled.\n");
|
||||
goto read_super_error;
|
||||
}
|
||||
if (osb->s_mount_opt & OCFS2_MOUNT_GRPQUOTA &&
|
||||
!OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
||||
OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) {
|
||||
status = -EINVAL;
|
||||
mlog(ML_ERROR, "Group quotas were requested, but this "
|
||||
"filesystem does not have the feature enabled.\n");
|
||||
goto read_super_error;
|
||||
}
|
||||
|
||||
status = ocfs2_verify_userspace_stack(osb, &parsed_options);
|
||||
if (status)
|
||||
@ -1245,6 +1235,40 @@ static struct file_system_type ocfs2_fs_type = {
|
||||
.next = NULL
|
||||
};
|
||||
|
||||
static int ocfs2_check_set_options(struct super_block *sb,
|
||||
struct mount_options *options)
|
||||
{
|
||||
if (options->mount_opt & OCFS2_MOUNT_USRQUOTA &&
|
||||
!OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
||||
OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) {
|
||||
mlog(ML_ERROR, "User quotas were requested, but this "
|
||||
"filesystem does not have the feature enabled.\n");
|
||||
return 0;
|
||||
}
|
||||
if (options->mount_opt & OCFS2_MOUNT_GRPQUOTA &&
|
||||
!OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
||||
OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) {
|
||||
mlog(ML_ERROR, "Group quotas were requested, but this "
|
||||
"filesystem does not have the feature enabled.\n");
|
||||
return 0;
|
||||
}
|
||||
if (options->mount_opt & OCFS2_MOUNT_POSIX_ACL &&
|
||||
!OCFS2_HAS_INCOMPAT_FEATURE(sb, OCFS2_FEATURE_INCOMPAT_XATTR)) {
|
||||
mlog(ML_ERROR, "ACL support requested but extended attributes "
|
||||
"feature is not enabled\n");
|
||||
return 0;
|
||||
}
|
||||
/* No ACL setting specified? Use XATTR feature... */
|
||||
if (!(options->mount_opt & (OCFS2_MOUNT_POSIX_ACL |
|
||||
OCFS2_MOUNT_NO_POSIX_ACL))) {
|
||||
if (OCFS2_HAS_INCOMPAT_FEATURE(sb, OCFS2_FEATURE_INCOMPAT_XATTR))
|
||||
options->mount_opt |= OCFS2_MOUNT_POSIX_ACL;
|
||||
else
|
||||
options->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ocfs2_parse_options(struct super_block *sb,
|
||||
char *options,
|
||||
struct mount_options *mopt,
|
||||
@ -1392,40 +1416,19 @@ static int ocfs2_parse_options(struct super_block *sb,
|
||||
mopt->mount_opt |= OCFS2_MOUNT_INODE64;
|
||||
break;
|
||||
case Opt_usrquota:
|
||||
/* We check only on remount, otherwise features
|
||||
* aren't yet initialized. */
|
||||
if (is_remount && !OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
||||
OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) {
|
||||
mlog(ML_ERROR, "User quota requested but "
|
||||
"filesystem feature is not set\n");
|
||||
status = 0;
|
||||
goto bail;
|
||||
}
|
||||
mopt->mount_opt |= OCFS2_MOUNT_USRQUOTA;
|
||||
break;
|
||||
case Opt_grpquota:
|
||||
if (is_remount && !OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
||||
OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) {
|
||||
mlog(ML_ERROR, "Group quota requested but "
|
||||
"filesystem feature is not set\n");
|
||||
status = 0;
|
||||
goto bail;
|
||||
}
|
||||
mopt->mount_opt |= OCFS2_MOUNT_GRPQUOTA;
|
||||
break;
|
||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
||||
case Opt_acl:
|
||||
mopt->mount_opt |= OCFS2_MOUNT_POSIX_ACL;
|
||||
mopt->mount_opt &= ~OCFS2_MOUNT_NO_POSIX_ACL;
|
||||
break;
|
||||
case Opt_noacl:
|
||||
mopt->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL;
|
||||
mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL;
|
||||
break;
|
||||
#else
|
||||
case Opt_acl:
|
||||
case Opt_noacl:
|
||||
printk(KERN_INFO "ocfs2 (no)acl options not supported\n");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
mlog(ML_ERROR,
|
||||
"Unrecognized mount option \"%s\" "
|
||||
@ -1502,12 +1505,10 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
|
||||
if (opts & OCFS2_MOUNT_INODE64)
|
||||
seq_printf(s, ",inode64");
|
||||
|
||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
||||
if (opts & OCFS2_MOUNT_POSIX_ACL)
|
||||
seq_printf(s, ",acl");
|
||||
else
|
||||
seq_printf(s, ",noacl");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -163,6 +163,7 @@ const struct inode_operations ocfs2_symlink_inode_operations = {
|
||||
.getxattr = generic_getxattr,
|
||||
.listxattr = ocfs2_listxattr,
|
||||
.removexattr = generic_removexattr,
|
||||
.fiemap = ocfs2_fiemap,
|
||||
};
|
||||
const struct inode_operations ocfs2_fast_symlink_inode_operations = {
|
||||
.readlink = ocfs2_readlink,
|
||||
@ -174,4 +175,5 @@ const struct inode_operations ocfs2_fast_symlink_inode_operations = {
|
||||
.getxattr = generic_getxattr,
|
||||
.listxattr = ocfs2_listxattr,
|
||||
.removexattr = generic_removexattr,
|
||||
.fiemap = ocfs2_fiemap,
|
||||
};
|
||||
|
@ -98,10 +98,8 @@ static struct ocfs2_xattr_def_value_root def_xv = {
|
||||
|
||||
struct xattr_handler *ocfs2_xattr_handlers[] = {
|
||||
&ocfs2_xattr_user_handler,
|
||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
||||
&ocfs2_xattr_acl_access_handler,
|
||||
&ocfs2_xattr_acl_default_handler,
|
||||
#endif
|
||||
&ocfs2_xattr_trusted_handler,
|
||||
&ocfs2_xattr_security_handler,
|
||||
NULL
|
||||
@ -109,12 +107,10 @@ struct xattr_handler *ocfs2_xattr_handlers[] = {
|
||||
|
||||
static struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = {
|
||||
[OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler,
|
||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
||||
[OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS]
|
||||
= &ocfs2_xattr_acl_access_handler,
|
||||
[OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT]
|
||||
= &ocfs2_xattr_acl_default_handler,
|
||||
#endif
|
||||
[OCFS2_XATTR_INDEX_TRUSTED] = &ocfs2_xattr_trusted_handler,
|
||||
[OCFS2_XATTR_INDEX_SECURITY] = &ocfs2_xattr_security_handler,
|
||||
};
|
||||
@ -6064,7 +6060,7 @@ static int ocfs2_value_metas_in_xattr_header(struct super_block *sb,
|
||||
* to the extent block, so just calculate a maximum record num.
|
||||
*/
|
||||
if (!xv->xr_list.l_tree_depth)
|
||||
*num_recs += xv->xr_list.l_next_free_rec;
|
||||
*num_recs += le16_to_cpu(xv->xr_list.l_next_free_rec);
|
||||
else
|
||||
*num_recs += ocfs2_clusters_for_bytes(sb,
|
||||
XATTR_SIZE_MAX);
|
||||
|
@ -40,10 +40,8 @@ struct ocfs2_security_xattr_info {
|
||||
extern struct xattr_handler ocfs2_xattr_user_handler;
|
||||
extern struct xattr_handler ocfs2_xattr_trusted_handler;
|
||||
extern struct xattr_handler ocfs2_xattr_security_handler;
|
||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
||||
extern struct xattr_handler ocfs2_xattr_acl_access_handler;
|
||||
extern struct xattr_handler ocfs2_xattr_acl_default_handler;
|
||||
#endif
|
||||
extern struct xattr_handler *ocfs2_xattr_handlers[];
|
||||
|
||||
ssize_t ocfs2_listxattr(struct dentry *, char *, size_t);
|
||||
|
@ -62,5 +62,7 @@ struct fiemap {
|
||||
#define FIEMAP_EXTENT_MERGED 0x00001000 /* File does not natively
|
||||
* support extents. Result
|
||||
* merged for efficiency. */
|
||||
#define FIEMAP_EXTENT_SHARED 0x00002000 /* Space shared with other
|
||||
* files. */
|
||||
|
||||
#endif /* _LINUX_FIEMAP_H */
|
||||
|
Loading…
Reference in New Issue
Block a user