From c98d4bca73763595c95664b6eb36f3c29b637a42 Mon Sep 17 00:00:00 2001 From: ericm Date: Fri, 28 Oct 2005 23:18:05 +0000 Subject: [PATCH] land b1_4_acl on b_release_1_4_6: add Posix ACL support. --- lustre/include/liblustre.h | 46 ++++++++++ lustre/include/linux/lustre_cfg.h | 1 + lustre/include/linux/lustre_idl.h | 15 ++-- lustre/include/linux/lustre_mds.h | 12 ++- lustre/include/linux/lustre_net.h | 2 + lustre/include/linux/obd.h | 4 +- lustre/llite/file.c | 83 +++++++++++++++++- lustre/llite/llite_internal.h | 26 ++++-- lustre/llite/llite_lib.c | 84 +++++++++++++++--- lustre/llite/namei.c | 3 +- lustre/llite/special.c | 1 + lustre/llite/symlink.c | 1 + lustre/llite/xattr.c | 51 ++++++----- lustre/mdc/mdc_locks.c | 39 ++++----- lustre/mdc/mdc_request.c | 104 ++++++++++++++++++++--- lustre/mds/handler.c | 173 ++++++++++++++++++++++++++++++++------ lustre/mds/mds_internal.h | 3 + lustre/mds/mds_open.c | 25 ++++++ lustre/mds/mds_xattr.c | 12 ++- lustre/ptlrpc/pack_generic.c | 59 ++++++++++++- lustre/ptlrpc/ptlrpc_module.c | 1 + lustre/tests/cfg/local.sh | 4 + lustre/tests/conf-sanity.sh | 6 +- lustre/tests/llmount.sh | 2 +- lustre/tests/llrmount.sh | 2 +- lustre/tests/local.sh | 9 +- lustre/tests/lov.sh | 8 +- lustre/tests/sanity.sh | 38 +++++++++ lustre/tests/test-framework.sh | 25 ++++-- lustre/tests/uml.sh | 8 +- lustre/utils/lconf | 6 +- lustre/utils/llmount.c | 3 + lustre/utils/wirecheck.c | 4 + lustre/utils/wiretest.c | 4 + 34 files changed, 727 insertions(+), 137 deletions(-) diff --git a/lustre/include/liblustre.h b/lustre/include/liblustre.h index f88243a..98669cb 100644 --- a/lustre/include/liblustre.h +++ b/lustre/include/liblustre.h @@ -811,6 +811,52 @@ struct file_lock { result; \ }) +/* ACL */ +struct posix_acl_entry { + short e_tag; + unsigned short e_perm; + unsigned int e_id; +}; + +struct posix_acl { + atomic_t a_refcount; + unsigned int a_count; + struct posix_acl_entry a_entries[0]; +}; + +typedef struct { + __u16 e_tag; + __u16 e_perm; + __u32 e_id; +} xattr_acl_entry; + +typedef struct { + __u32 a_version; + xattr_acl_entry a_entries[0]; +} xattr_acl_header; + +static inline size_t xattr_acl_size(int count) +{ + return sizeof(xattr_acl_header) + count * sizeof(xattr_acl_entry); +} + +static inline +struct posix_acl * posix_acl_from_xattr(const void *value, size_t size) +{ + return NULL; +} + +static inline +int posix_acl_valid(const struct posix_acl *acl) +{ + return 0; +} + +static inline +void posix_acl_release(struct posix_acl *acl) +{ +} + #ifndef ENOTSUPP #define ENOTSUPP ENOTSUP #endif diff --git a/lustre/include/linux/lustre_cfg.h b/lustre/include/linux/lustre_cfg.h index 6c2f8a6..acc8fe8 100644 --- a/lustre/include/linux/lustre_cfg.h +++ b/lustre/include/linux/lustre_cfg.h @@ -243,5 +243,6 @@ struct lustre_mount_data { #define LMD_FLG_FLOCK 0x0001 #define LMD_FLG_USER_XATTR 0x0002 +#define LMD_FLG_ACL 0x0004 #endif // _LUSTRE_CFG_H diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index d0f9900..9313cb4 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -207,10 +207,14 @@ static inline void lustre_msg_set_op_flags(struct lustre_msg *msg, int flags) /* Connect flags */ -#define OBD_CONNECT_RDONLY 0x1ULL -#define OBD_CONNECT_SRVLOCK 0x10ULL /* server takes locks for client */ - -#define MDS_CONNECT_SUPPORTED (OBD_CONNECT_RDONLY) +#define OBD_CONNECT_RDONLY 0x0001ULL +#define OBD_CONNECT_SRVLOCK 0x0010ULL /* server takes locks for client */ +#define OBD_CONNECT_ACL 0x0080ULL +#define OBD_CONNECT_USER_XATTR 0x0100ULL + +#define MDS_CONNECT_SUPPORTED (OBD_CONNECT_RDONLY | \ + OBD_CONNECT_ACL | \ + OBD_CONNECT_USER_XATTR) #define OST_CONNECT_SUPPORTED (OBD_CONNECT_SRVLOCK) #define ECHO_CONNECT_SUPPORTED (0) @@ -380,6 +384,7 @@ struct lov_mds_md_v1 { /* LOV EA mds/wire data (little-endian) */ #define OBD_MD_FLXATTR (0x0000001000000000ULL) /* xattr */ #define OBD_MD_FLXATTRLS (0x0000002000000000ULL) /* xattr list */ #define OBD_MD_FLXATTRRM (0x0000004000000000ULL) /* xattr remove */ +#define OBD_MD_FLACL (0x0000008000000000ULL) /* ACL */ #define OBD_MD_FLGETATTR (OBD_MD_FLID | OBD_MD_FLATIME | OBD_MD_FLMTIME | \ OBD_MD_FLCTIME | OBD_MD_FLSIZE | OBD_MD_FLBLKSZ | \ @@ -581,7 +586,7 @@ struct mds_body { __u32 generation; __u32 suppgid; __u32 eadatasize; - __u32 padding_1; /* also fix lustre_swab_mds_body */ + __u32 aclsize; __u32 padding_2; /* also fix lustre_swab_mds_body */ __u32 padding_3; /* also fix lustre_swab_mds_body */ __u32 padding_4; /* also fix lustre_swab_mds_body */ diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h index 1eb5c58..cc06517 100644 --- a/lustre/include/linux/lustre_mds.h +++ b/lustre/include/linux/lustre_mds.h @@ -13,6 +13,7 @@ #ifdef __KERNEL__ # include # include +# include #endif #include #include @@ -36,8 +37,9 @@ struct ll_file_data; #define LUSTRE_MDC_NAME "mdc" struct lustre_md { - struct mds_body *body; - struct lov_stripe_md *lsm; + struct mds_body *body; + struct lov_stripe_md *lsm; + struct posix_acl *posix_acl; }; struct mdc_op_data { @@ -126,6 +128,11 @@ struct mds_file_data { struct dentry *mfd_dentry; }; +/* ACL */ +#define LUSTRE_POSIX_ACL_MAX_ENTRIES (32) +#define LUSTRE_POSIX_ACL_MAX_SIZE \ + (xattr_acl_size(LUSTRE_POSIX_ACL_MAX_ENTRIES)) + /* mds/mds_reint.c */ int mds_reint_rec(struct mds_update_record *r, int offset, struct ptlrpc_request *req, struct lustre_handle *); @@ -176,6 +183,7 @@ int mdc_enqueue(struct obd_export *exp, int mdc_init_ea_size(struct obd_export *mdc_exp, struct obd_export *lov_exp); int mdc_req2lustre_md(struct ptlrpc_request *req, int offset, struct obd_export *exp, struct lustre_md *md); +void mdc_free_lustre_md(struct obd_export *exp, struct lustre_md *md); int mdc_getstatus(struct obd_export *exp, struct ll_fid *rootfid); int mdc_getattr(struct obd_export *exp, struct ll_fid *fid, obd_valid valid, unsigned int ea_size, diff --git a/lustre/include/linux/lustre_net.h b/lustre/include/linux/lustre_net.h index e537a20..00347ab 100644 --- a/lustre/include/linux/lustre_net.h +++ b/lustre/include/linux/lustre_net.h @@ -720,6 +720,8 @@ int lustre_pack_request(struct ptlrpc_request *, int count, int *lens, char **bufs); int lustre_pack_reply(struct ptlrpc_request *, int count, int *lens, char **bufs); +void lustre_shrink_reply(struct ptlrpc_request *req, + int segment, unsigned int newlen, int move_data); void lustre_free_reply_state(struct ptlrpc_reply_state *rs); int lustre_msg_size(int count, int *lengths); int lustre_unpack_msg(struct lustre_msg *m, int len); diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index a681ad9..844b5b9 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -361,7 +361,6 @@ struct mds_obd { int mds_has_lov_desc; struct lov_desc mds_lov_desc; obd_id *mds_lov_objids; - int mds_lov_objids_valid; int mds_lov_nextid_set; struct file *mds_lov_objid_filp; unsigned long *mds_client_bitmap; @@ -371,6 +370,9 @@ struct mds_obd { struct lustre_quota_ctxt mds_quota_ctxt; atomic_t mds_quotachecking; struct semaphore mds_health_sem; + unsigned long mds_lov_objids_valid:1, + mds_fl_user_xattr:1, + mds_fl_acl:1; }; struct echo_obd { diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 2a2827b..49ca28b 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1078,7 +1078,7 @@ static int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file, rc = mdc_req2lustre_md(req, 1, exp, &md); if (rc) GOTO(out, rc); - ll_update_inode(f->f_dentry->d_inode, md.body, md.lsm); + ll_update_inode(f->f_dentry->d_inode, &md); rc = ll_local_open(f, &oit, fd); if (rc) @@ -1526,7 +1526,7 @@ int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it) struct ptlrpc_request *req = NULL; struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode); struct ll_fid fid; - unsigned long valid = OBD_MD_FLGETATTR; + obd_valid valid = OBD_MD_FLGETATTR; int ealen = 0; if (S_ISREG(inode->i_mode)) { @@ -1591,6 +1591,84 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de, } #endif +static +int lustre_check_acl(struct inode *inode, int mask) +{ + struct ll_inode_info *lli = ll_i2info(inode); + struct posix_acl *acl; + int rc; + ENTRY; + + spin_lock(&lli->lli_lock); + acl = posix_acl_dup(lli->lli_posix_acl); + spin_unlock(&lli->lli_lock); + + if (!acl) + RETURN(-EAGAIN); + + rc = posix_acl_permission(inode, acl, mask); + posix_acl_release(acl); + + RETURN(rc); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)) +int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), mask %o\n", + inode->i_ino, inode->i_generation, inode, mask); + return generic_permission(inode, mask, lustre_check_acl); +} +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) +int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd) +#else +int ll_inode_permission(struct inode *inode, int mask) +#endif +{ + int mode = inode->i_mode; + int rc; + + CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), mask %o\n", + inode->i_ino, inode->i_generation, inode, mask); + + if ((mask & MAY_WRITE) && IS_RDONLY(inode) && + (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) + return -EROFS; + if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) + return -EACCES; + if (current->fsuid == inode->i_uid) { + mode >>= 6; + } else if (1) { + if (((mode >> 3) & mask & S_IRWXO) != mask) + goto check_groups; + rc = lustre_check_acl(inode, mask); + if (rc == -EAGAIN) + goto check_groups; + if (rc == -EACCES) + goto check_capabilities; + return rc; + } else { +check_groups: + if (in_group_p(inode->i_gid)) + mode >>= 3; + } + if ((mode & mask & S_IRWXO) == mask) + return 0; + +check_capabilities: + if (!(mask & MAY_EXEC) || + (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode)) + if (capable(CAP_DAC_OVERRIDE)) + return 0; + + if (capable(CAP_DAC_READ_SEARCH) && ((mask == MAY_READ) || + (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))) + return 0; + return -EACCES; +} +#endif + struct file_operations ll_file_operations = { .read = ll_file_read, .write = ll_file_write, @@ -1631,6 +1709,7 @@ struct inode_operations ll_file_inode_operations = { #else .revalidate_it = ll_inode_revalidate_it, #endif + .permission = ll_inode_permission, .setxattr = ll_setxattr, .getxattr = ll_getxattr, .listxattr = ll_listxattr, diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 3ddf759..c969c0e 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -76,6 +76,9 @@ struct ll_inode_info { struct file_operations *ll_save_ffop; struct file_operations *ll_save_wfop; struct file_operations *ll_save_wrfop; + + struct posix_acl *lli_posix_acl; + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) struct inode lli_vfs_inode; #endif @@ -128,10 +131,11 @@ struct ll_ra_info { }; /* flags for sbi->ll_flags */ -#define LL_SBI_NOLCK 0x1 /* DLM locking disabled (directio-only) */ -#define LL_SBI_CHECKSUM 0x2 /* checksum each page as it's written */ -#define LL_SBI_FLOCK 0x4 -#define LL_SBI_USER_XATTR 0x8 /* support user xattr */ +#define LL_SBI_NOLCK 0x01 /* DLM locking disabled (directio-only) */ +#define LL_SBI_CHECKSUM 0x02 /* checksum each page as it's written */ +#define LL_SBI_FLOCK 0x04 +#define LL_SBI_USER_XATTR 0x08 /* support user xattr */ +#define LL_SBI_ACL 0x10 /* support ACL */ struct ll_sb_info { struct list_head ll_list; @@ -371,6 +375,11 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct lookup_intent *it, struct kstat *stat); #endif struct ll_file_data *ll_file_data_get(void); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) +int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd); +#else +int ll_inode_permission(struct inode *inode, int mask); +#endif /* llite/dcache.c */ void ll_intent_drop_lock(struct lookup_intent *); @@ -398,8 +407,7 @@ int ll_setattr(struct dentry *de, struct iattr *attr); int ll_statfs(struct super_block *sb, struct kstatfs *sfs); int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs, unsigned long maxage); -void ll_update_inode(struct inode *inode, struct mds_body *body, - struct lov_stripe_md *lsm); +void ll_update_inode(struct inode *inode, struct lustre_md *md); void ll_read_inode2(struct inode *inode, void *opaque); int ll_iocontrol(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); @@ -545,9 +553,9 @@ static inline __u64 ll_file_maxbytes(struct inode *inode) /* llite/xattr.c */ int ll_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); -int ll_getxattr(struct dentry *dentry, const char *name, - void *buffer, size_t size); -int ll_listxattr(struct dentry *dentry, char *buffer, size_t size); +ssize_t ll_getxattr(struct dentry *dentry, const char *name, + void *buffer, size_t size); +ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size); int ll_removexattr(struct dentry *dentry, const char *name); #endif /* LLITE_INTERNAL_H */ diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index acccc1e..73979ec 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -155,6 +155,10 @@ int lustre_common_fill_super(struct super_block *sb, char *mdc, char *osc) if (sb->s_flags & MS_RDONLY) data->ocd_connect_flags |= OBD_CONNECT_RDONLY; + if (sbi->ll_flags & LL_SBI_USER_XATTR) + data->ocd_connect_flags |= OBD_CONNECT_USER_XATTR; + if (sbi->ll_flags & LL_SBI_ACL) + data->ocd_connect_flags |= OBD_CONNECT_ACL; if (sbi->ll_flags & LL_SBI_FLOCK) { sbi->ll_fop = &ll_file_operations_flock; @@ -178,6 +182,9 @@ int lustre_common_fill_super(struct super_block *sb, char *mdc, char *osc) if (err) GOTO(out_mdc, err); + /* async connect is surely finished by now */ + *data = class_exp2cliimp(sbi->ll_mdc_exp)->imp_connect_data; + LASSERT(osfs.os_bsize); sb->s_blocksize = osfs.os_bsize; sb->s_blocksize_bits = log2(osfs.os_bsize); @@ -185,6 +192,19 @@ int lustre_common_fill_super(struct super_block *sb, char *mdc, char *osc) sb->s_maxbytes = PAGE_CACHE_MAXBYTES; sbi->ll_namelen = osfs.os_namelen; + if ((sbi->ll_flags & LL_SBI_USER_XATTR) && + !(data->ocd_connect_flags & OBD_CONNECT_USER_XATTR)) { + LCONSOLE_INFO("Disabling user_xattr feature because " + "it is not supported on the server\n"); + sbi->ll_flags &= ~LL_SBI_USER_XATTR; + } + + if (((sbi->ll_flags & LL_SBI_ACL) == 0) != + ((data->ocd_connect_flags & OBD_CONNECT_ACL) == 0)) { + CERROR("Server return unexpected ACL flags\n"); + GOTO(out_mdc, err = -EBADE); + } + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) /* We set sb->s_dev equal on all lustre clients in order to support * NFS export clustering. NFSD requires that the FSID be the same @@ -241,7 +261,8 @@ int lustre_common_fill_super(struct super_block *sb, char *mdc, char *osc) /* make root inode * XXX: move this to after cbd setup? */ err = mdc_getattr(sbi->ll_mdc_exp, &rootfid, - OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS, 0, &request); + OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLACL, + 0, &request); if (err) { CERROR("mdc_getattr failed for root: rc = %d\n", err); GOTO(out_osc, err); @@ -260,8 +281,7 @@ int lustre_common_fill_super(struct super_block *sb, char *mdc, char *osc) ptlrpc_req_finished(request); if (root == NULL || is_bad_inode(root)) { - if (md.lsm != NULL) - obd_free_memmd(sbi->ll_osc_exp, &md.lsm); + mdc_free_lustre_md(sbi->ll_osc_exp, &md); CERROR("lustre_lite: bad iget4 for root\n"); GOTO(out_root, err = -EBADF); } @@ -462,6 +482,16 @@ void ll_options(char *options, char **ost, char **mdc, int *flags) *flags &= ~tmp; continue; } + tmp = ll_set_opt("acl", this_char, LL_SBI_ACL); + if (tmp) { + *flags |= tmp; + continue; + } + tmp = ll_set_opt("noacl", this_char, LL_SBI_ACL); + if (tmp) { + *flags &= ~tmp; + continue; + } } EXIT; } @@ -529,6 +559,7 @@ int lustre_process_log(struct lustre_mount_data *lmd, char * profile, class_uuid_t uuid; struct obd_uuid mdc_uuid; struct llog_ctxt *ctxt; + struct obd_connect_data *ocd = NULL; int rc = 0; int err; ENTRY; @@ -549,7 +580,7 @@ int lustre_process_log(struct lustre_mount_data *lmd, char * profile, rc = class_process_config(lcfg); lustre_cfg_free(lcfg); if (rc < 0) - GOTO(out, err); + GOTO(out, rc); lustre_cfg_bufs_reset(&bufs, name); lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_MDC_NAME); @@ -586,7 +617,14 @@ int lustre_process_log(struct lustre_mount_data *lmd, char * profile, if (rc) GOTO(out_cleanup, rc); - rc = obd_connect(&mdc_conn, obd, &mdc_uuid, NULL /* ocd */); + if (lmd->lmd_flags & LMD_FLG_ACL) { + OBD_ALLOC(ocd, sizeof(*ocd)); + if (ocd == NULL) + GOTO(out_cleanup, rc = -ENOMEM); + ocd->ocd_connect_flags |= OBD_CONNECT_ACL; + } + + rc = obd_connect(&mdc_conn, obd, &mdc_uuid, ocd); if (rc) { CERROR("cannot connect to %s: rc = %d\n", lmd->lmd_mds, rc); GOTO(out_cleanup, rc); @@ -650,7 +688,8 @@ out_del_uuid: CERROR("del MDC UUID failed: rc = %d\n", err); out: - + if (ocd) + OBD_FREE(ocd, sizeof(*ocd)); RETURN(rc); } @@ -702,6 +741,8 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent) sbi->ll_flags |= LL_SBI_FLOCK; if (lmd->lmd_flags & LMD_FLG_USER_XATTR) sbi->ll_flags |= LL_SBI_USER_XATTR; + if (lmd->lmd_flags & LMD_FLG_ACL) + sbi->ll_flags |= LL_SBI_ACL; /* generate a string unique to this super, let's try the address of the super itself.*/ @@ -884,6 +925,13 @@ void ll_clear_inode(struct inode *inode) strlen(lli->lli_symlink_name) + 1); lli->lli_symlink_name = NULL; } + + if (lli->lli_posix_acl) { + LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1); + posix_acl_release(lli->lli_posix_acl); + lli->lli_posix_acl = NULL; + } + lli->lli_inode_magic = LLI_INODE_DEAD; EXIT; @@ -987,7 +1035,7 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) * (bug 6196) */ inode_setattr(inode, attr); - ll_update_inode(inode, md.body, md.lsm); + ll_update_inode(inode, &md); ptlrpc_req_finished(request); if (!lsm || !S_ISREG(inode->i_mode)) { @@ -1201,10 +1249,11 @@ void ll_inode_size_unlock(struct inode *inode, int unlock_lsm) up(&lli->lli_size_sem); } -void ll_update_inode(struct inode *inode, struct mds_body *body, - struct lov_stripe_md *lsm) +void ll_update_inode(struct inode *inode, struct lustre_md *md) { struct ll_inode_info *lli = ll_i2info(inode); + struct mds_body *body = md->body; + struct lov_stripe_md *lsm = md->lsm; LASSERT ((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0)); if (lsm != NULL) { @@ -1243,6 +1292,15 @@ void ll_update_inode(struct inode *inode, struct mds_body *body, inode->i_sb->s_blocksize); } + LASSERT(!md->posix_acl || (body->valid & OBD_MD_FLACL)); + if (body->valid & OBD_MD_FLACL) { + spin_lock(&lli->lli_lock); + if (lli->lli_posix_acl) + posix_acl_release(lli->lli_posix_acl); + lli->lli_posix_acl = md->posix_acl; + spin_unlock(&lli->lli_lock); + } + if (body->valid & OBD_MD_FLID) inode->i_ino = body->ino; if (body->valid & OBD_MD_FLATIME) @@ -1317,7 +1375,7 @@ void ll_read_inode2(struct inode *inode, void *opaque) LTIME_S(inode->i_atime) = 0; LTIME_S(inode->i_ctime) = 0; inode->i_rdev = 0; - ll_update_inode(inode, md->body, md->lsm); + ll_update_inode(inode, md); /* OIDEBUG(inode); */ @@ -1534,14 +1592,12 @@ int ll_prep_inode(struct obd_export *exp, struct inode **inode, RETURN(rc); if (*inode) { - ll_update_inode(*inode, md.body, md.lsm); + ll_update_inode(*inode, &md); } else { LASSERT(sb); *inode = ll_iget(sb, md.body->ino, &md); if (*inode == NULL || is_bad_inode(*inode)) { - /* free the lsm if we allocated one above */ - if (md.lsm != NULL) - obd_free_memmd(exp, &md.lsm); + mdc_free_lustre_md(exp, &md); rc = -ENOMEM; CERROR("new_inode -fatal: rc %d\n", rc); } diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 2ee2f85..9b440dc 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -76,7 +76,7 @@ static int ll_test_inode(struct inode *inode, void *opaque) /* Apply the attributes in 'opaque' to this inode */ if (!(inode->i_state & (I_FREEING | I_CLEAR))) - ll_update_inode(inode, md->body, md->lsm); + ll_update_inode(inode, md); return 1; } @@ -895,6 +895,7 @@ struct inode_operations ll_dir_inode_operations = { .create = ll_create_nd, .getattr_it = ll_getattr, #endif + .permission = ll_inode_permission, .setxattr = ll_setxattr, .getxattr = ll_getxattr, .listxattr = ll_listxattr, diff --git a/lustre/llite/special.c b/lustre/llite/special.c index 328801d..82697ee 100644 --- a/lustre/llite/special.c +++ b/lustre/llite/special.c @@ -332,6 +332,7 @@ struct inode_operations ll_special_inode_operations = { #else .revalidate_it = ll_inode_revalidate_it, #endif + .permission = ll_inode_permission, .setxattr = ll_setxattr, .getxattr = ll_getxattr, .listxattr = ll_listxattr, diff --git a/lustre/llite/symlink.c b/lustre/llite/symlink.c index 0b5d990..f069420 100644 --- a/lustre/llite/symlink.c +++ b/lustre/llite/symlink.c @@ -161,6 +161,7 @@ struct inode_operations ll_fast_symlink_inode_operations = { #else .getattr_it = ll_getattr, #endif + .permission = ll_inode_permission, .setxattr = ll_setxattr, .getxattr = ll_getxattr, .listxattr = ll_listxattr, diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index d3180c1..d05e914 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -47,7 +47,7 @@ #define XATTR_USER_T (1) #define XATTR_TRUSTED_T (2) #define XATTR_SECURITY_T (3) -#define XATTR_POSIXACL_T (4) +#define XATTR_ACL_T (4) #define XATTR_OTHER_T (5) static @@ -55,7 +55,7 @@ int get_xattr_type(const char *name) { if (!strcmp(name, XATTR_NAME_ACL_ACCESS) || !strcmp(name, XATTR_NAME_ACL_DEFAULT)) - return XATTR_POSIXACL_T; + return XATTR_ACL_T; if (!strncmp(name, XATTR_USER_PREFIX, sizeof(XATTR_USER_PREFIX) - 1)) @@ -73,6 +73,21 @@ int get_xattr_type(const char *name) } static +int xattr_type_filter(struct ll_sb_info *sbi, int xattr_type) +{ + if (xattr_type == XATTR_ACL_T && !(sbi->ll_flags & LL_SBI_ACL)) + return -EOPNOTSUPP; + if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR)) + return -EOPNOTSUPP; + if (xattr_type == XATTR_TRUSTED_T && !capable(CAP_SYS_ADMIN)) + return -EPERM; + if (xattr_type == XATTR_OTHER_T) + return -EOPNOTSUPP; + + return 0; +} + +static int ll_setxattr_common(struct inode *inode, const char *name, const void *value, size_t size, int flags, __u64 valid) @@ -86,19 +101,17 @@ int ll_setxattr_common(struct inode *inode, const char *name, lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_SETXATTR); xattr_type = get_xattr_type(name); - if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR)) - RETURN(-EOPNOTSUPP); - if (xattr_type == XATTR_TRUSTED_T && !capable(CAP_SYS_ADMIN)) - RETURN(-EPERM); - if (xattr_type == XATTR_OTHER_T) - RETURN(-EOPNOTSUPP); + rc = xattr_type_filter(sbi, xattr_type); + if (rc) + RETURN(rc); ll_inode2fid(&fid, inode); rc = mdc_setxattr(sbi->ll_mdc_exp, &fid, valid, name, value, size, 0, flags, &req); if (rc) { if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) { - CWARN("disable user_xattr from now on\n"); + LCONSOLE_INFO("Disabling user_xattr feature because " + "it is not supported on the server\n"); sbi->ll_flags &= ~LL_SBI_USER_XATTR; } RETURN(rc); @@ -109,7 +122,7 @@ int ll_setxattr_common(struct inode *inode, const char *name, } int ll_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) + const void *value, size_t size, int flags) { struct inode *inode = dentry->d_inode; @@ -164,12 +177,9 @@ int ll_getxattr_common(struct inode *inode, const char *name, } xattr_type = get_xattr_type(name); - if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR)) - RETURN(-EOPNOTSUPP); - if (xattr_type == XATTR_TRUSTED_T && !capable(CAP_SYS_ADMIN)) - RETURN(-EPERM); - if (xattr_type == XATTR_OTHER_T) - RETURN(-EOPNOTSUPP); + rc = xattr_type_filter(sbi, xattr_type); + if (rc) + RETURN(rc); do_getxattr: ll_inode2fid(&fid, inode); @@ -177,7 +187,8 @@ do_getxattr: size, &req); if (rc) { if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) { - CWARN("disable user_xattr from now on\n"); + LCONSOLE_INFO("Disabling user_xattr feature because " + "it is not supported on the server\n"); sbi->ll_flags &= ~LL_SBI_USER_XATTR; } RETURN(rc); @@ -219,8 +230,8 @@ out: RETURN(rc); } -int ll_getxattr(struct dentry *dentry, const char *name, - void *buffer, size_t size) +ssize_t ll_getxattr(struct dentry *dentry, const char *name, + void *buffer, size_t size) { struct inode *inode = dentry->d_inode; @@ -233,7 +244,7 @@ int ll_getxattr(struct dentry *dentry, const char *name, return ll_getxattr_common(inode, name, buffer, size, OBD_MD_FLXATTR); } -int ll_listxattr(struct dentry *dentry, char *buffer, size_t size) +ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size) { struct inode *inode = dentry->d_inode; diff --git a/lustre/mdc/mdc_locks.c b/lustre/mdc/mdc_locks.c index 4363263..08f0fd9 100644 --- a/lustre/mdc/mdc_locks.c +++ b/lustre/mdc/mdc_locks.c @@ -244,16 +244,14 @@ int mdc_enqueue(struct obd_export *exp, ldlm_policy_data_t policy = { .l_inodebits = { MDS_INODELOCK_LOOKUP } }; int size[5] = {sizeof(struct ldlm_request), sizeof(struct ldlm_intent)}; int rc, flags = extra_lock_flags | LDLM_FL_HAS_INTENT; - int repsize[4] = {sizeof(struct ldlm_reply), - sizeof(struct mds_body), - obddev->u.cli.cl_max_mds_easize, - obddev->u.cli.cl_max_mds_cookiesize}; + int repbufcnt = 3, repsize[4] = {sizeof(struct ldlm_reply), + sizeof(struct mds_body), + obddev->u.cli.cl_max_mds_easize}; struct ldlm_reply *dlm_rep; struct ldlm_intent *lit; struct ldlm_request *lockreq; void *eadata; unsigned long irqflags; - int reply_buffers = 0; ENTRY; // LDLM_DEBUG_NOLOCK("mdsintent=%s,name=%s,dir=%lu", @@ -291,9 +289,8 @@ int mdc_enqueue(struct obd_export *exp, /* pack the intended request */ mdc_open_pack(req, 2, data, it->it_create_mode, 0, it->it_flags, lmm, lmmsize); - /* get ready for the reply */ - reply_buffers = 3; - req->rq_replen = lustre_msg_size(3, repsize); + + repsize[repbufcnt++] = LUSTRE_POSIX_ACL_MAX_SIZE; } else if (it->it_op & IT_UNLINK) { size[2] = sizeof(struct mds_rec_unlink); size[3] = data->namelen + 1; @@ -309,11 +306,11 @@ int mdc_enqueue(struct obd_export *exp, /* pack the intended request */ mdc_unlink_pack(req, 2, data); - /* get ready for the reply */ - reply_buffers = 4; - req->rq_replen = lustre_msg_size(4, repsize); + + repsize[repbufcnt++] = obddev->u.cli.cl_max_mds_cookiesize; } else if (it->it_op & (IT_GETATTR | IT_LOOKUP)) { - obd_valid valid = OBD_MD_FLGETATTR | OBD_MD_FLEASIZE; + obd_valid valid = OBD_MD_FLGETATTR | OBD_MD_FLEASIZE | + OBD_MD_FLACL; size[2] = sizeof(struct mds_body); size[3] = data->namelen + 1; @@ -331,9 +328,8 @@ int mdc_enqueue(struct obd_export *exp, /* pack the intended request */ mdc_getattr_pack(req, valid, 2, it->it_flags, data); - /* get ready for the reply */ - reply_buffers = 3; - req->rq_replen = lustre_msg_size(3, repsize); + + repsize[repbufcnt++] = LUSTRE_POSIX_ACL_MAX_SIZE; } else if (it->it_op == IT_READDIR) { policy.l_inodebits.bits = MDS_INODELOCK_UPDATE; req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 1, @@ -341,14 +337,15 @@ int mdc_enqueue(struct obd_export *exp, if (!req) RETURN(-ENOMEM); - /* get ready for the reply */ - reply_buffers = 1; - req->rq_replen = lustre_msg_size(1, repsize); - } else { + repbufcnt = 1; + } else { LBUG(); RETURN(-EINVAL); } + /* get ready for the reply */ + req->rq_replen = lustre_msg_size(repbufcnt, repsize); + mdc_get_rpc_lock(obddev->u.cli.cl_rpc_lock, it); rc = ldlm_cli_enqueue(exp, req, obddev->obd_namespace, res_id, lock_type,&policy,lock_mode, &flags,cb_blocking, @@ -407,8 +404,8 @@ int mdc_enqueue(struct obd_export *exp, it->it_op,it->d.lustre.it_disposition,it->d.lustre.it_status); /* We know what to expect, so we do any byte flipping required here */ - LASSERT(reply_buffers == 4 || reply_buffers == 3 || reply_buffers == 1); - if (reply_buffers >= 3) { + LASSERT(repbufcnt == 4 || repbufcnt == 1); + if (repbufcnt == 4) { struct mds_body *body; body = lustre_swab_repbuf(req, 1, sizeof (*body), diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index f52d543..0783098 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -98,13 +98,14 @@ int mdc_getstatus(struct obd_export *exp, struct ll_fid *rootfid) 0); } +static int mdc_getattr_common(struct obd_export *exp, unsigned int ea_size, - struct ptlrpc_request *req) + unsigned int acl_size, struct ptlrpc_request *req) { struct mds_body *body; void *eadata; int rc; - int size[2] = {sizeof(*body), 0}; + int size[3] = {sizeof(*body)}; int bufcount = 1; ENTRY; @@ -115,6 +116,11 @@ int mdc_getattr_common(struct obd_export *exp, unsigned int ea_size, CDEBUG(D_INODE, "reserved %u bytes for MD/symlink in packet\n", ea_size); } + if (acl_size) { + size[bufcount++] = acl_size; + CDEBUG(D_INODE, "reserved %u bytes for ACL\n", acl_size); + } + req->rq_replen = lustre_msg_size(bufcount, size); mdc_get_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL); @@ -152,7 +158,7 @@ int mdc_getattr(struct obd_export *exp, struct ll_fid *fid, struct ptlrpc_request *req; struct mds_body *body; int size = sizeof(*body); - int rc; + int acl_size = 0, rc; ENTRY; /* XXX do we need to make another request here? We just did a getattr @@ -169,7 +175,11 @@ int mdc_getattr(struct obd_export *exp, struct ll_fid *fid, body->eadatasize = ea_size; mdc_pack_req_body(req); - rc = mdc_getattr_common(exp, ea_size, req); + /* currently only root inode will call us with FLACL */ + if (valid & OBD_MD_FLACL) + acl_size = LUSTRE_POSIX_ACL_MAX_SIZE; + + rc = mdc_getattr_common(exp, ea_size, acl_size, req); if (rc != 0) { ptlrpc_req_finished (req); req = NULL; @@ -202,7 +212,7 @@ int mdc_getattr_name(struct obd_export *exp, struct ll_fid *fid, LASSERT (strnlen (filename, namelen) == namelen - 1); memcpy(lustre_msg_buf(req->rq_reqmsg, 1, namelen), filename, namelen); - rc = mdc_getattr_common(exp, ea_size, req); + rc = mdc_getattr_common(exp, ea_size, 0, req); if (rc != 0) { ptlrpc_req_finished (req); req = NULL; @@ -339,6 +349,45 @@ void mdc_store_inode_generation(struct ptlrpc_request *req, int reqoff, rec->cr_replayfid.generation, rec->cr_replayfid.id); } +static +int mdc_unpack_acl(struct obd_export *exp, struct ptlrpc_request *req, + struct lustre_md *md, unsigned int offset) +{ + struct mds_body *body = md->body; + struct posix_acl *acl; + void *buf; + int rc; + + if (!body->aclsize) + return 0; + + buf = lustre_msg_buf(req->rq_repmsg, offset, body->aclsize); + if (!buf) { + CERROR("aclsize %u, bufcount %u, bufsize %u\n", + body->aclsize, req->rq_repmsg->bufcount, + (req->rq_repmsg->bufcount <= offset) ? -1 : + req->rq_repmsg->buflens[offset]); + return -EPROTO; + } + + acl = posix_acl_from_xattr(buf, body->aclsize); + if (IS_ERR(acl)) { + rc = PTR_ERR(acl); + CERROR("convert xattr to acl: %d\n", rc); + return rc; + } + + rc = posix_acl_valid(acl); + if (rc) { + CERROR("validate acl: %d\n", rc); + posix_acl_release(acl); + return rc; + } + + md->posix_acl = acl; + return 0; +} + int mdc_req2lustre_md(struct ptlrpc_request *req, int offset, struct obd_export *exp, struct lustre_md *md) @@ -352,6 +401,7 @@ int mdc_req2lustre_md(struct ptlrpc_request *req, int offset, md->body = lustre_msg_buf(req->rq_repmsg, offset, sizeof (*md->body)); LASSERT (md->body != NULL); LASSERT_REPSWABBED (req, offset); + offset++; if (md->body->valid & OBD_MD_FLEASIZE) { int lmmsize; @@ -364,17 +414,48 @@ int mdc_req2lustre_md(struct ptlrpc_request *req, int offset, RETURN(-EPROTO); } lmmsize = md->body->eadatasize; - lmm = lustre_msg_buf(req->rq_repmsg, offset + 1, lmmsize); + lmm = lustre_msg_buf(req->rq_repmsg, offset, lmmsize); LASSERT (lmm != NULL); - LASSERT_REPSWABBED (req, offset + 1); + LASSERT_REPSWABBED (req, offset); rc = obd_unpackmd(exp, &md->lsm, lmm, lmmsize); - if (rc >= 0) { - LASSERT (rc >= sizeof (*md->lsm)); - rc = 0; - } + if (rc < 0) + RETURN(rc); + + LASSERT (rc >= sizeof (*md->lsm)); + rc = 0; + + offset++; } + + /* for ACL, it's possible that FLACL is set but aclsize is zero. + * only when aclsize != 0 there's an actual segment for ACL in + * reply buffer. + */ + if ((md->body->valid & OBD_MD_FLACL) && md->body->aclsize) { + rc = mdc_unpack_acl(exp, req, md, offset); + if (rc) + GOTO(err_out, rc); + offset++; + } +out: RETURN(rc); + +err_out: + if (md->lsm) + obd_free_memmd(exp, &md->lsm); + goto out; +} + +void mdc_free_lustre_md(struct obd_export *exp, struct lustre_md *md) +{ + if (md->lsm) + obd_free_memmd(exp, &md->lsm); + + if (md->posix_acl) { + posix_acl_release(md->posix_acl); + md->posix_acl = NULL; + } } static void mdc_commit_open(struct ptlrpc_request *req) @@ -1187,6 +1268,7 @@ MODULE_DESCRIPTION("Lustre Metadata Client"); MODULE_LICENSE("GPL"); EXPORT_SYMBOL(mdc_req2lustre_md); +EXPORT_SYMBOL(mdc_free_lustre_md); EXPORT_SYMBOL(mdc_change_cbdata); EXPORT_SYMBOL(mdc_getstatus); EXPORT_SYMBOL(mdc_getattr); diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 659c381..a61e4b6 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -260,7 +260,7 @@ static int mds_connect(struct lustre_handle *conn, struct obd_device *obd, { struct obd_export *exp; struct mds_export_data *med; - struct mds_client_data *mcd; + struct mds_client_data *mcd = NULL; int rc, abort_recovery; ENTRY; @@ -293,9 +293,21 @@ static int mds_connect(struct lustre_handle *conn, struct obd_device *obd, if (data != NULL) { data->ocd_connect_flags &= MDS_CONNECT_SUPPORTED; + + if (!obd->u.mds.mds_fl_user_xattr) + data->ocd_connect_flags &= ~OBD_CONNECT_USER_XATTR; + exp->exp_connect_flags = data->ocd_connect_flags; } + if ((obd->u.mds.mds_fl_acl == 0) != + ((exp->exp_connect_flags & OBD_CONNECT_ACL) == 0)) { + CWARN("%s require ACL support but %s doesn't\n", + obd->u.mds.mds_fl_acl ? "MDS" : "client", + obd->u.mds.mds_fl_acl ? "client" : "MDS"); + GOTO(out, rc = -EBADE); + } + OBD_ALLOC(mcd, sizeof(*mcd)); if (!mcd) { CERROR("mds: out of memory for client data\n"); @@ -512,6 +524,49 @@ int mds_pack_md(struct obd_device *obd, struct lustre_msg *msg, int offset, RETURN(rc); } +static +int mds_pack_posix_acl(struct inode *inode, struct lustre_msg *repmsg, + struct mds_body *repbody, int repoff) +{ + struct dentry de = { .d_inode = inode }; + int buflen, rc; + ENTRY; + + LASSERT(repbody->aclsize == 0); + LASSERT(repmsg->bufcount > repoff); + + buflen = lustre_msg_buflen(repmsg, repoff); + if (!buflen) + GOTO(out, 0); + + if (!inode->i_op || !inode->i_op->getxattr) + GOTO(out, 0); + + lock_24kernel(); + rc = inode->i_op->getxattr(&de, XATTR_NAME_ACL_ACCESS, + lustre_msg_buf(repmsg, repoff, buflen), + buflen); + unlock_24kernel(); + + if (rc >= 0) + repbody->aclsize = rc; + else if (rc != -ENODATA) { + CERROR("buflen %d, get acl: %d\n", buflen, rc); + RETURN(rc); + } + EXIT; +out: + repbody->valid |= OBD_MD_FLACL; + return 0; +} + +int mds_pack_acl(struct mds_export_data *med, struct inode *inode, + struct lustre_msg *repmsg, struct mds_body *repbody, + int repoff) +{ + return mds_pack_posix_acl(inode, repmsg, repbody, repoff); +} + static int mds_getattr_internal(struct obd_device *obd, struct dentry *dentry, struct ptlrpc_request *req, struct mds_body *reqbody, int reply_off) @@ -529,10 +584,11 @@ static int mds_getattr_internal(struct obd_device *obd, struct dentry *dentry, mds_pack_inode2fid(&body->fid1, inode); mds_pack_inode2body(body, inode); + reply_off++; if ((S_ISREG(inode->i_mode) && (reqbody->valid & OBD_MD_FLEASIZE)) || (S_ISDIR(inode->i_mode) && (reqbody->valid & OBD_MD_FLDIREA))) { - rc = mds_pack_md(obd, req->rq_repmsg, reply_off + 1, body, + rc = mds_pack_md(obd, req->rq_repmsg, reply_off, body, inode, 1); /* If we have LOV EA data, the OST holds size, atime, mtime */ @@ -540,13 +596,17 @@ static int mds_getattr_internal(struct obd_device *obd, struct dentry *dentry, !(body->valid & OBD_MD_FLDIREA)) body->valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | OBD_MD_FLATIME | OBD_MD_FLMTIME); + + lustre_shrink_reply(req, reply_off, body->eadatasize, 0); + if (body->eadatasize) + reply_off++; } else if (S_ISLNK(inode->i_mode) && (reqbody->valid & OBD_MD_LINKNAME) != 0) { - char *symname = lustre_msg_buf(req->rq_repmsg, reply_off + 1,0); + char *symname = lustre_msg_buf(req->rq_repmsg, reply_off, 0); int len; LASSERT (symname != NULL); /* caller prepped reply */ - len = req->rq_repmsg->buflens[reply_off + 1]; + len = req->rq_repmsg->buflens[reply_off]; rc = inode->i_op->readlink(dentry, symname, len); if (rc < 0) { @@ -562,6 +622,21 @@ static int mds_getattr_internal(struct obd_device *obd, struct dentry *dentry, symname[rc] = 0; /* NULL terminate */ rc = 0; } + reply_off++; + } + + if (rc) + RETURN(rc); + + if ((req->rq_export->exp_connect_flags & OBD_CONNECT_ACL) && + (reqbody->valid & OBD_MD_FLACL)) { + rc = mds_pack_acl(&req->rq_export->exp_mds_data, + inode, req->rq_repmsg, + body, reply_off); + + lustre_shrink_reply(req, reply_off, body->aclsize, 0); + if (body->aclsize) + reply_off++; } RETURN(rc); @@ -572,7 +647,7 @@ static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct inode *inode, { struct mds_obd *mds = mds_req2mds(req); struct mds_body *body; - int rc = 0, size[2] = {sizeof(*body)}, bufcount = 1; + int rc, size[2] = {sizeof(*body)}, bufcount = 1; ENTRY; body = lustre_msg_buf(req->rq_reqmsg, offset, sizeof (*body)); @@ -581,25 +656,24 @@ static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct inode *inode, if ((S_ISREG(inode->i_mode) && (body->valid & OBD_MD_FLEASIZE)) || (S_ISDIR(inode->i_mode) && (body->valid & OBD_MD_FLDIREA))) { - int ret; down(&inode->i_sem); - ret = fsfilt_get_md(req->rq_export->exp_obd, inode, NULL, 0); + rc = fsfilt_get_md(req->rq_export->exp_obd, inode, NULL, 0); up(&inode->i_sem); CDEBUG(D_INODE, "got %d bytes MD data for inode %lu\n", rc, inode->i_ino); - if (ret < 0) { - if (ret != -ENODATA) { + if (rc < 0) { + if (rc != -ENODATA) { CERROR("error getting inode %lu MD: rc = %d\n", - inode->i_ino, ret); - /* should we return ret in req->rq_status? */ + inode->i_ino, rc); + RETURN(rc); } size[bufcount] = 0; - } else if (ret > mds->mds_max_mdsize) { + } else if (rc > mds->mds_max_mdsize) { size[bufcount] = 0; CERROR("MD size %d larger than maximum possible %u\n", - ret, mds->mds_max_mdsize); + rc, mds->mds_max_mdsize); } else { - size[bufcount] = ret; + size[bufcount] = rc; } bufcount++; } else if (S_ISLNK(inode->i_mode) && (body->valid & OBD_MD_LINKNAME)) { @@ -612,21 +686,42 @@ static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct inode *inode, inode->i_size + 1, body->eadatasize); } + if ((req->rq_export->exp_connect_flags & OBD_CONNECT_ACL) && + (body->valid & OBD_MD_FLACL)) { + struct dentry de = { .d_inode = inode }; + + size[bufcount] = 0; + if (inode->i_op && inode->i_op->getxattr) { + lock_24kernel(); + rc = inode->i_op->getxattr(&de, XATTR_NAME_ACL_ACCESS, + NULL, 0); + unlock_24kernel(); + + if (rc < 0) { + if (rc != -ENODATA) { + CERROR("got acl size: %d\n", rc); + RETURN(rc); + } + } else + size[bufcount] = rc; + } + bufcount++; + } + if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETATTR_PACK)) { CERROR("failed MDS_GETATTR_PACK test\n"); req->rq_status = -ENOMEM; - GOTO(out, rc = -ENOMEM); + RETURN(-ENOMEM); } rc = lustre_pack_reply(req, bufcount, size, NULL); if (rc) { CERROR("lustre_pack_reply failed: rc %d\n", rc); - GOTO(out, req->rq_status = rc); + req->rq_status = rc; + RETURN(rc); } - EXIT; - out: - return(rc); + RETURN(0); } static int mds_getattr_name(int offset, struct ptlrpc_request *req, @@ -1443,6 +1538,25 @@ int mds_update_server_data(struct obd_device *obd, int force_sync) RETURN(rc); } +static +void fsoptions_to_mds_flags(struct mds_obd *mds, const char *options) +{ + const char *p = options; + + while (*options) { + while (*p && *p != ',') + p++; + + if ((p - options == sizeof("user_xattr") - 1) && + !memcmp(options, "user_xattr", sizeof("user_xattr") - 1)) + mds->mds_fl_user_xattr = 1; + else if ((p - options == sizeof("acl") - 1) && + !memcmp(options, "acl", sizeof("acl") - 1)) + mds->mds_fl_acl = 1; + + options = ++p; + } +} /* mount the file system (secretly). lustre_cfg parameters are: * 1 = device @@ -1484,9 +1598,11 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf) * should be moved to somewhere else like startup scripts or lconf. */ sprintf(options, "iopen_nopriv"); - if (LUSTRE_CFG_BUFLEN(lcfg, 4) > 0 && lustre_cfg_buf(lcfg, 4)) + if (LUSTRE_CFG_BUFLEN(lcfg, 4) > 0 && lustre_cfg_buf(lcfg, 4)) { sprintf(options + strlen(options), ",%s", lustre_cfg_string(lcfg, 4)); + fsoptions_to_mds_flags(mds, options); + } mnt = do_kern_mount(lustre_cfg_string(lcfg, 2), 0, lustre_cfg_string(lcfg, 1), (void *)options); @@ -1897,10 +2013,10 @@ static int mds_intent_policy(struct ldlm_namespace *ns, struct lustre_handle lockh = { 0 }; struct ldlm_lock *new_lock = NULL; int getattr_part = MDS_INODELOCK_UPDATE; - int rc, offset = 2, repsize[4] = {sizeof(struct ldlm_reply), - sizeof(struct mds_body), - mds->mds_max_mdsize, - mds->mds_max_cookiesize}; + int rc, offset = 2; + int repbufcnt = 3, repsize[4] = {sizeof(struct ldlm_reply), + sizeof(struct mds_body), + mds->mds_max_mdsize}; ENTRY; LASSERT(req != NULL); @@ -1921,8 +2037,13 @@ static int mds_intent_policy(struct ldlm_namespace *ns, LDLM_DEBUG(lock, "intent policy, opc: %s", ldlm_it2str(it->opc)); - rc = lustre_pack_reply(req, it->opc == IT_UNLINK ? 4 : 3, repsize, - NULL); + if ((req->rq_export->exp_connect_flags & OBD_CONNECT_ACL) && + (it->opc & (IT_OPEN | IT_GETATTR | IT_LOOKUP))) + repsize[repbufcnt++] = LUSTRE_POSIX_ACL_MAX_SIZE; + else if (it->opc & IT_UNLINK) + repsize[repbufcnt++] = mds->mds_max_cookiesize; + + rc = lustre_pack_reply(req, repbufcnt, repsize, NULL); if (rc) RETURN(req->rq_status = rc); diff --git a/lustre/mds/mds_internal.h b/lustre/mds/mds_internal.h index 606cf1b..7636f33 100644 --- a/lustre/mds/mds_internal.h +++ b/lustre/mds/mds_internal.h @@ -201,6 +201,9 @@ int mds_pack_md(struct obd_device *, struct lustre_msg *, int offset, void mds_pack_inode2fid(struct ll_fid *fid, struct inode *inode); void mds_pack_inode2body(struct mds_body *body, struct inode *inode); #endif +int mds_pack_acl(struct mds_export_data *med, struct inode *inode, + struct lustre_msg *repmsg, struct mds_body *repbody, + int repoff); /* mds/mds_xattr.c */ int mds_setxattr(struct ptlrpc_request *req); diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index 9964a16..e20d5fb 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -554,6 +554,18 @@ static void reconstruct_open(struct mds_update_record *rec, int offset, OBD_MD_FLATIME | OBD_MD_FLMTIME); } + lustre_shrink_reply(req, 2, body->eadatasize, 0); + + if (req->rq_export->exp_connect_flags & OBD_CONNECT_ACL) { + int acl_off = body->eadatasize ? 3 : 2; + + rc = mds_pack_acl(med, dchild->d_inode, req->rq_repmsg, + body, acl_off); + lustre_shrink_reply(req, acl_off, body->aclsize, 0); + if (!req->rq_status && rc) + req->rq_status = rc; + } + /* If we have -EEXIST as the status, and we were asked to create * exclusively, we can tell we failed because the file already existed. */ @@ -687,6 +699,19 @@ static int mds_finish_open(struct ptlrpc_request *req, struct dentry *dchild, } up(&dchild->d_inode->i_sem); + lustre_shrink_reply(req, 2, body->eadatasize, 0); + + if (req->rq_export->exp_connect_flags & OBD_CONNECT_ACL) { + int acl_off = body->eadatasize ? 3 : 2; + + rc = mds_pack_acl(&req->rq_export->exp_mds_data, + dchild->d_inode, req->rq_repmsg, + body, acl_off); + lustre_shrink_reply(req, acl_off, body->aclsize, 0); + if (rc) + RETURN(rc); + } + intent_set_disposition(rep, DISP_OPEN_OPEN); mfd = mds_dentry_open(dchild, mds->mds_vfsmnt, flags, req); if (IS_ERR(mfd)) diff --git a/lustre/mds/mds_xattr.c b/lustre/mds/mds_xattr.c index 69a7af5..aa12812 100644 --- a/lustre/mds/mds_xattr.c +++ b/lustre/mds/mds_xattr.c @@ -62,6 +62,11 @@ static int mds_getxattr_pack_msg(struct ptlrpc_request *req, return -EFAULT; } + if (!(req->rq_export->exp_connect_flags & + OBD_CONNECT_USER_XATTR) && + (strncmp(xattr_name, "user.", 5) == 0)) + return -EOPNOTSUPP; + if (inode->i_op && inode->i_op->getxattr) rc = inode->i_op->getxattr(de, xattr_name, NULL, 0); } else if (body->valid & OBD_MD_FLXATTRLS) { @@ -245,11 +250,16 @@ int mds_setxattr_internal(struct ptlrpc_request *req, struct mds_body *body) body->valid & OBD_MD_FLXATTR ? "set" : "remove", xattr_name); - if (!strncmp(xattr_name, "trusted.", 8)) { + if (strncmp(xattr_name, "trusted.", 8) == 0) { if (!strcmp(xattr_name, "trusted."XATTR_LUSTRE_MDS_LOV_EA)) GOTO(out_dput, rc = -EACCES); } + if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_USER_XATTR) && + (strncmp(xattr_name, "user.", 5) == 0)) { + GOTO(out_dput, rc = -EOPNOTSUPP); + } + /* filter_op simply use setattr one */ handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL); if (IS_ERR(handle)) diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 1abbdab..2061a8a 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -195,6 +195,59 @@ int lustre_pack_reply (struct ptlrpc_request *req, RETURN (0); } +/* + * shrink @segment to size @newlen. if @move_data is non-zero, we also move + * data forward from @segment + 1. + * + * if @newlen == 0, we remove the segment completely, but we still keep the + * totally bufcount the same to save possible data moving. this will leave a + * unused segment with size 0 at the tail, but that's ok. + * + * CAUTION: + * + if any buffers higher than @segment has been filled in, must call shrink + * with non-zero @move_data. + * + caller should NOT keep pointers to msg buffers which higher than @segment + * after call shrink. + */ +void lustre_shrink_reply(struct ptlrpc_request *req, + int segment, unsigned int newlen, int move_data) +{ + struct lustre_msg *msg = req->rq_repmsg; + char *tail = NULL, *newpos; + int tail_len = 0, n; + + LASSERT(req->rq_reply_state); + LASSERT(msg); + LASSERT(msg->bufcount > segment); + LASSERT(msg->buflens[segment] >= newlen); + + if (msg->buflens[segment] == newlen) + return; + + if (move_data && msg->bufcount > segment + 1) { + tail = lustre_msg_buf(msg, segment + 1, 0); + for (n = segment + 1; n < msg->bufcount; n++) + tail_len += size_round(msg->buflens[n]); + } + + msg->buflens[segment] = newlen; + + if (tail && tail_len) { + newpos = lustre_msg_buf(msg, segment + 1, 0); + LASSERT(newpos <= tail); + if (newpos != tail) + memcpy(newpos, tail, tail_len); + } + + if (newlen == 0 && msg->bufcount > segment + 1) { + memmove(&msg->buflens[segment], &msg->buflens[segment + 1], + (msg->bufcount - segment - 1) * sizeof(__u32)); + msg->buflens[msg->bufcount - 1] = 0; + } + + req->rq_replen = lustre_msg_size(msg->bufcount, msg->buflens); +} + void lustre_free_reply_state (struct ptlrpc_reply_state *rs) { PTLRPC_RS_DEBUG_LRU_DEL(rs); @@ -550,7 +603,7 @@ void lustre_swab_mds_body (struct mds_body *b) __swab32s (&b->generation); __swab32s (&b->suppgid); __swab32s (&b->eadatasize); - __swab32s (&b->padding_1); + __swab32s (&b->aclsize); __swab32s (&b->padding_2); __swab32s (&b->padding_3); __swab32s (&b->padding_4); @@ -1637,6 +1690,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct mds_body, eadatasize)); LASSERTF((int)sizeof(((struct mds_body *)0)->eadatasize) == 4, " found %lld\n", (long long)(int)sizeof(((struct mds_body *)0)->eadatasize)); + LASSERTF((int)offsetof(struct mds_body, aclsize) == 152, " found %lld\n", + (long long)(int)offsetof(struct mds_body, aclsize)); + LASSERTF((int)sizeof(((struct mds_body *)0)->aclsize) == 4, " found %lld\n", + (long long)(int)sizeof(((struct mds_body *)0)->aclsize)); LASSERTF(FMODE_READ == 1, " found %lld\n", (long long)FMODE_READ); LASSERTF(FMODE_WRITE == 2, " found %lld\n", diff --git a/lustre/ptlrpc/ptlrpc_module.c b/lustre/ptlrpc/ptlrpc_module.c index 35d91ee..5333e94 100644 --- a/lustre/ptlrpc/ptlrpc_module.c +++ b/lustre/ptlrpc/ptlrpc_module.c @@ -149,6 +149,7 @@ EXPORT_SYMBOL(ptlrpc_service_health_check); EXPORT_SYMBOL(lustre_msg_swabbed); EXPORT_SYMBOL(lustre_pack_request); EXPORT_SYMBOL(lustre_pack_reply); +EXPORT_SYMBOL(lustre_shrink_reply); EXPORT_SYMBOL(lustre_free_reply_state); EXPORT_SYMBOL(lustre_msg_size); EXPORT_SYMBOL(lustre_unpack_msg); diff --git a/lustre/tests/cfg/local.sh b/lustre/tests/cfg/local.sh index 924587a..66d48f6 100644 --- a/lustre/tests/cfg/local.sh +++ b/lustre/tests/cfg/local.sh @@ -27,6 +27,10 @@ FSTYPE=${FSTYPE:-ext3} TIMEOUT=${TIMEOUT:-20} UPCALL=${UPCALL:-DEFAULT} +MDSOPT=${MDSOPT:-"user_xattr,acl"} +CLIENTOPT=${CLIENTOPT:-"user_xattr,acl"} +MOUNTOPT=${MOUNTOPT:-"user_xattr,acl"} + STRIPE_BYTES=${STRIPE_BYTES:-1048576} STRIPES_PER_OBJ=${STRIPES_PER_OBJ:-0} diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 7157cc2..0674610 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -226,7 +226,7 @@ test_5b() { [ -d $MOUNT ] || mkdir -p $MOUNT $LCONF --nosetup --node client_facet $XMLCONFIG > /dev/null - llmount -o nettype=$NETTYPE $mds_HOST://mds_svc/client_facet $MOUNT && exit 1 + llmount -o nettype=$NETTYPE,$MOUNTOPT $mds_HOST://mds_svc/client_facet $MOUNT && exit 1 # cleanup client modules $LCONF --cleanup --nosetup --node client_facet $XMLCONFIG > /dev/null @@ -247,7 +247,7 @@ test_5c() { [ -d $MOUNT ] || mkdir -p $MOUNT $LCONF --nosetup --node client_facet $XMLCONFIG > /dev/null - llmount -o nettype=$NETTYPE $mds_HOST://wrong_mds_svc/client_facet $MOUNT && return 1 + llmount -o nettype=$NETTYPE,$MOUNTOPT $mds_HOST://wrong_mds_svc/client_facet $MOUNT && return 1 # cleanup client modules $LCONF --cleanup --nosetup --node client_facet $XMLCONFIG > /dev/null @@ -268,7 +268,7 @@ test_5d() { [ -d $MOUNT ] || mkdir -p $MOUNT $LCONF --nosetup --node client_facet $XMLCONFIG > /dev/null - llmount -o nettype=$NETTYPE $mds_HOST://mds_svc/client_facet $MOUNT || return 1 + llmount -o nettype=$NETTYPE,$MOUNTOPT $mds_HOST://mds_svc/client_facet $MOUNT || return 1 umount $MOUNT || return 2 # cleanup client modules diff --git a/lustre/tests/llmount.sh b/lustre/tests/llmount.sh index 90ef09d..24e5521 100755 --- a/lustre/tests/llmount.sh +++ b/lustre/tests/llmount.sh @@ -32,5 +32,5 @@ ${LCONF} $NOMOD $portals_opt $lustre_opt $debug_opt $node_opt ${REFORMAT:---refo $conf_opt || exit 2 if [ "$MOUNT2" ]; then - $LLMOUNT -v `hostname`:/mds1/client $MOUNT2 || exit 3 + $LLMOUNT -v -o user_xattr,acl `hostname`:/mds1/client $MOUNT2 || exit 3 fi diff --git a/lustre/tests/llrmount.sh b/lustre/tests/llrmount.sh index d198c82..5e49d89 100755 --- a/lustre/tests/llrmount.sh +++ b/lustre/tests/llrmount.sh @@ -33,5 +33,5 @@ ${LCONF} $NOMOD $portals_opt $lustre_opt $node_opt $@ $conf_opt || exit 2 [ $DEBUG ] && sysctl -w lnet.debug=$DEBUG if [ "$MOUNT2" ]; then - $LLMOUNT -v `hostname`:/mds1/client $MOUNT2 || exit 3 + $LLMOUNT -v -o user_xattr,acl `hostname`:/mds1/client $MOUNT2 || exit 3 fi diff --git a/lustre/tests/local.sh b/lustre/tests/local.sh index 3d28052..3207c18 100755 --- a/lustre/tests/local.sh +++ b/lustre/tests/local.sh @@ -18,7 +18,8 @@ NETTYPE=${NETTYPE:-tcp} OSTDEV=${OSTDEV:-$TMP/ost1-`hostname`} OSTSIZE=${OSTSIZE:-400000} -CLIENTOPT="user_xattr,${CLIENTOPT:-""}" +MDS_MOUNT_OPTS="user_xattr,acl,${MDS_MOUNT_OPTS:-""}" +CLIENTOPT="user_xattr,acl,${CLIENTOPT:-""}" # specific journal size for the ost, in MB JSIZE=${JSIZE:-0} @@ -61,13 +62,13 @@ ${LMC} --add node --node $HOSTNAME || exit 10 ${LMC} --add net --node $HOSTNAME --nid `h2$NETTYPE $HOSTNAME` --nettype $NETTYPE || exit 11 ${LMC} --add net --node client --nid '*' --nettype $NETTYPE || exit 12 +# configure mds server [ "x$MDS_MOUNT_OPTS" != "x" ] && MDS_MOUNT_OPTS="--mountfsoptions $MDS_MOUNT_OPTS" -# configure mds server ${LMC} --add mds --node $HOSTNAME --mds mds1 --fstype $FSTYPE \ - --dev $MDSDEV \ - $MDS_MOUNT_OPTS --size $MDSSIZE $JARG $IARG $MDSOPT || exit 20 + --dev $MDSDEV $MDS_MOUNT_OPTS \ + --size $MDSSIZE $JARG $IARG $MDSOPT || exit 20 [ "x$OST_MOUNT_OPTS" != "x" ] && OST_MOUNT_OPTS="--mountfsoptions $OST_MOUNT_OPTS" diff --git a/lustre/tests/lov.sh b/lustre/tests/lov.sh index 2fa6b35..fbf563f 100755 --- a/lustre/tests/lov.sh +++ b/lustre/tests/lov.sh @@ -27,7 +27,8 @@ ECHO_CLIENT=${ECHO_CLIENT:-} STRIPE_BYTES=${STRIPE_BYTES:-1048576} STRIPES_PER_OBJ=${STRIPES_PER_OBJ:-$((OSTCOUNT -1))} -CLIENTOPT="user_xattr,${CLIENTOPT:-""}" +MDS_MOUNT_OPTS="user_xattr,acl,${MDS_MOUNT_OPTS:-""}" +CLIENTOPT="user_xattr,acl,${CLIENTOPT:-""}" # specific journal size for the ost, in MB JSIZE=${JSIZE:-0} @@ -42,8 +43,11 @@ ${LMC} --add net --node $HOSTNAME --nid $HOSTNAME --nettype $NETTYPE || exit 11 ${LMC} --add net --node client --nid '*' --nettype $NETTYPE || exit 12 # configure mds server +[ "x$MDS_MOUNT_OPTS" != "x" ] && + MDS_MOUNT_OPTS="--mountfsoptions $MDS_MOUNT_OPTS" + ${LMC} --format --add mds --node $HOSTNAME --mds mds1 --fstype $FSTYPE \ - --dev $MDSDEV --size $MDSSIZE $MDSOPT || exit 20 + --dev $MDSDEV $MDS_MOUNT_OPTS --size $MDSSIZE $MDSOPT || exit 20 # configure ost ${LMC} --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES \ diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 4570e08..59e2a8f 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -2762,6 +2762,44 @@ test_102() { } run_test 102 "user xattr test =====================" +run_acl_subtest() +{ + $SAVE_PWD/acl/run $SAVE_PWD/acl/$1.test + return $? +} + +test_103 () { + SAVE_UMASK=`umask` + umask 0022 + cd $DIR + + [ "$UID" != 0 ] && echo "skipping $TESTNAME (must run as root)" && return + [ -z "`mount | grep " $DIR .*\"`" ] && echo "skipping $TESTNAME (must have acl)" && return + + echo "performing cp ..." + run_acl_subtest cp || error + echo "performing getfacl-noacl..." + run_acl_subtest getfacl-noacl || error + echo "performing misc..." + run_acl_subtest misc || error +# XXX add back permission test when we support supplementary groups. +# echo "performing permissions..." +# run_acl_subtest permissions || error + echo "performing setfacl..." + run_acl_subtest setfacl || error + + # inheritance test got from HP + echo "performing inheritance..." + cp $SAVE_PWD/acl/make-tree . || error + chmod +x make-tree || error + run_acl_subtest inheritance || error + rm -f make-tree + + cd $SAVED_PWD + umask $SAVE_UMASK +} +run_test 103 "==============acl test =============" + TMPDIR=$OLDTMPDIR TMP=$OLDTMP HOME=$OLDHOME diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index c04e5ce..339cbb5 100644 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -85,6 +85,7 @@ stop() { } zconf_mount() { + local OPTIONS client=$1 mnt=$2 @@ -92,17 +93,17 @@ zconf_mount() { # Only supply -o to mount if we have options if [ -n "$MOUNTOPT" ]; then - MOUNTOPT="-o $MOUNTOPT" + OPTIONS="-o $MOUNTOPT" fi if [ -x /sbin/mount.lustre ] ; then - do_node $client mount -t lustre $MOUNTOPT \ + do_node $client mount -t lustre $OPTIONS \ `facet_nid mds`:/mds_svc/client_facet $mnt || return 1 else # this is so cheating do_node $client $LCONF --nosetup --node client_facet $XMLCONFIG > \ /dev/null || return 2 - do_node $client $LLMOUNT $MOUNTOPT \ + do_node $client $LLMOUNT $OPTIONS \ `facet_nid mds`:/mds_svc/client_facet $mnt || return 4 fi @@ -346,20 +347,24 @@ add_facet() { } add_mds() { - facet=$1 + local MOUNT_OPTS + local facet=$1 shift rm -f ${facet}active add_facet $facet + [ "x$MDSOPT" != "x" ] && MOUNT_OPTS="--mountfsoptions $MDSOPT" do_lmc --add mds --node ${facet}_facet --mds ${facet}_svc \ - --fstype $FSTYPE $* $MDSOPT + --fstype $FSTYPE $* $MOUNT_OPTS } add_mdsfailover() { - facet=$1 + local MOUNT_OPTS + local facet=$1 shift add_facet ${facet}failover --lustre_upcall $UPCALL + [ "x$MDSOPT" != "x" ] && MOUNT_OPTS="--mountfsoptions $MDSOPT" do_lmc --add mds --node ${facet}failover_facet --mds ${facet}_svc \ - --fstype $FSTYPE $* $MDSOPT + --fstype $FSTYPE $* $MOUNT_OPTS } add_ost() { @@ -387,11 +392,13 @@ add_lov() { } add_client() { - facet=$1 + local MOUNT_OPTS + local facet=$1 mds=$2 shift; shift + [ "x$CLIENTOPT" != "x" ] && MOUNT_OPTS="--clientoptions $CLIENTOPT" add_facet $facet --lustre_upcall $UPCALL - do_lmc --add mtpt --node ${facet}_facet --mds ${mds}_svc $* $CLIENTOPT + do_lmc --add mtpt --node ${facet}_facet --mds ${mds}_svc $* $MOUNT_OPTS } diff --git a/lustre/tests/uml.sh b/lustre/tests/uml.sh index 7edf0ba..9c8955d 100644 --- a/lustre/tests/uml.sh +++ b/lustre/tests/uml.sh @@ -22,7 +22,8 @@ OSTFAILOVER=${OSTFAILOVER:-} MOUNT=${MOUNT:-/mnt/lustre} FSTYPE=${FSTYPE:-ext3} -CLIENTOPT="user_xattr,${CLIENTOPT:-""}" +MDS_MOUNT_OPTS="user_xattr,acl,${MDS_MOUNT_OPTS:-""}" +CLIENTOPT="user_xattr,acl,${CLIENTOPT:-""}" NETTYPE=${NETTYPE:-tcp} NIDTYPE=${NIDTYPE:-$NETTYPE} @@ -90,9 +91,12 @@ for NODE in `echo $MDSNODE $OSTNODES $CLIENTS | tr -s " " "\n" | sort -u`; do done # configure mds server +[ "x$MDS_MOUNT_OPTS" != "x" ] && + MDS_MOUNT_OPTS="--mountfsoptions $MDS_MOUNT_OPTS" + echo; echo "adding MDS on: $MDSNODE" ${LMC} -m $config --add mds --node $MDSNODE --mds mds1 --fstype $FSTYPE \ - --dev $MDSDEV --size $MDSSIZE $MDSOPT || exit 10 + --dev $MDSDEV $MDS_MOUNT_OPTS --size $MDSSIZE $MDSOPT || exit 10 # configure ost ${LMC} -m $config --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES \ diff --git a/lustre/utils/lconf b/lustre/utils/lconf index f69b313..fd2b407 100755 --- a/lustre/utils/lconf +++ b/lustre/utils/lconf @@ -778,7 +778,10 @@ def def_mount_options(fstype, target): #else: # mountfsoptions = "%s,extents,mballoc" % (mountfsoptions) elif target == 'mds': - mountfsoptions = "%s,user_xattr" % (mountfsoptions) + if config.user_xattr: + mountfsoptions = "%s,user_xattr" % (mountfsoptions) + if config.acl: + mountfsoptions = "%s,acl" % (mountfsoptions) return mountfsoptions return "" @@ -2607,6 +2610,7 @@ lconf_options = [ mounting (currently OST-only). Can be repeated.""", PARAMLIST), ('user_xattr', """Enable user_xattr support on MDS""", FLAG, 0), + ('acl', """Enable ACL support on MDS""", FLAG, 0), ] def main(): diff --git a/lustre/utils/llmount.c b/lustre/utils/llmount.c index 5a00ed7..7e8e41c 100644 --- a/lustre/utils/llmount.c +++ b/lustre/utils/llmount.c @@ -60,6 +60,7 @@ void usage(FILE *out) "\t-o: filesystem mount options:\n" "\t\tflock/noflock: enable/disable flock support\n" "\t\tuser_xattr/nouser_xattr: enable/disable user extended attributes\n" + "\t\t{no}acl: enable/disable ACL support\n" ); exit(out != stdout); } @@ -177,6 +178,8 @@ static const struct opt_map opt_map[] = { { "noflock", 1, 1, 0, LMD_FLG_FLOCK}, /* Disable flock support */ { "user_xattr", 0, 0, 0, LMD_FLG_USER_XATTR}, /* Enable get/set user xattr */ { "nouser_xattr", 1, 1, 0, LMD_FLG_USER_XATTR}, /* Disable user xattr */ + { "acl", 0, 0, 0, LMD_FLG_ACL}, /* Enable ACL support */ + { "noacl", 1, 1, 0, LMD_FLG_ACL}, /* Disable ACL support */ /* please add new mount options to usage message */ { NULL, 0, 0, 0, 0 } }; diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 08a4721..5de7cdf 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -328,6 +328,10 @@ check_mds_body(void) CHECK_MEMBER(mds_body, generation); CHECK_MEMBER(mds_body, suppgid); CHECK_MEMBER(mds_body, eadatasize); + CHECK_MEMBER(mds_body, aclsize); + CHECK_MEMBER(mds_body, padding_2); + CHECK_MEMBER(mds_body, padding_3); + CHECK_MEMBER(mds_body, padding_4); CHECK_VALUE(FMODE_READ); CHECK_VALUE(FMODE_WRITE); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index a6dab8e..8857bb5 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -812,6 +812,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct mds_body, eadatasize)); LASSERTF((int)sizeof(((struct mds_body *)0)->eadatasize) == 4, " found %lld\n", (long long)(int)sizeof(((struct mds_body *)0)->eadatasize)); + LASSERTF((int)offsetof(struct mds_body, aclsize) == 152, " found %lld\n", + (long long)(int)offsetof(struct mds_body, aclsize)); + LASSERTF((int)sizeof(((struct mds_body *)0)->aclsize) == 4, " found %lld\n", + (long long)(int)sizeof(((struct mds_body *)0)->aclsize)); LASSERTF(FMODE_READ == 1, " found %lld\n", (long long)FMODE_READ); LASSERTF(FMODE_WRITE == 2, " found %lld\n", -- 1.8.3.1