Whamcloud - gitweb
land b1_4_acl on b_release_1_4_6: add Posix ACL support.
authorericm <ericm>
Fri, 28 Oct 2005 23:18:05 +0000 (23:18 +0000)
committerericm <ericm>
Fri, 28 Oct 2005 23:18:05 +0000 (23:18 +0000)
34 files changed:
lustre/include/liblustre.h
lustre/include/linux/lustre_cfg.h
lustre/include/linux/lustre_idl.h
lustre/include/linux/lustre_mds.h
lustre/include/linux/lustre_net.h
lustre/include/linux/obd.h
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/namei.c
lustre/llite/special.c
lustre/llite/symlink.c
lustre/llite/xattr.c
lustre/mdc/mdc_locks.c
lustre/mdc/mdc_request.c
lustre/mds/handler.c
lustre/mds/mds_internal.h
lustre/mds/mds_open.c
lustre/mds/mds_xattr.c
lustre/ptlrpc/pack_generic.c
lustre/ptlrpc/ptlrpc_module.c
lustre/tests/cfg/local.sh
lustre/tests/conf-sanity.sh
lustre/tests/llmount.sh
lustre/tests/llrmount.sh
lustre/tests/local.sh
lustre/tests/lov.sh
lustre/tests/sanity.sh
lustre/tests/test-framework.sh
lustre/tests/uml.sh
lustre/utils/lconf
lustre/utils/llmount.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index f88243a..98669cb 100644 (file)
@@ -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
index 6c2f8a6..acc8fe8 100644 (file)
@@ -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
index d0f9900..9313cb4 100644 (file)
@@ -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 */
index 1eb5c58..cc06517 100644 (file)
@@ -13,6 +13,7 @@
 #ifdef __KERNEL__
 # include <linux/fs.h>
 # include <linux/dcache.h>
+# include <linux/xattr_acl.h>
 #endif
 #include <linux/lustre_handles.h>
 #include <libcfs/kp30.h>
@@ -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,
index e537a20..00347ab 100644 (file)
@@ -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);
index a681ad9..844b5b9 100644 (file)
@@ -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 {
index 2a2827b..49ca28b 100644 (file)
@@ -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,
index 3ddf759..c969c0e 100644 (file)
@@ -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 */
index acccc1e..73979ec 100644 (file)
@@ -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);
                 }
index 2ee2f85..9b440dc 100644 (file)
@@ -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,
index 328801d..82697ee 100644 (file)
@@ -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,
index 0b5d990..f069420 100644 (file)
@@ -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,
index d3180c1..d05e914 100644 (file)
@@ -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;
 
index 4363263..08f0fd9 100644 (file)
@@ -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),
index f52d543..0783098 100644 (file)
@@ -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);
index 659c381..a61e4b6 100644 (file)
@@ -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_off0);
                 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);
 
index 606cf1b..7636f33 100644 (file)
@@ -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);
index 9964a16..e20d5fb 100644 (file)
@@ -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))
index 69a7af5..aa12812 100644 (file)
@@ -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))
index 1abbdab..2061a8a 100644 (file)
@@ -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",
index 35d91ee..5333e94 100644 (file)
@@ -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);
index 924587a..66d48f6 100644 (file)
@@ -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}
 
index 7157cc2..0674610 100644 (file)
@@ -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
index 90ef09d..24e5521 100755 (executable)
@@ -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
index d198c82..5e49d89 100755 (executable)
@@ -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
index 3d28052..3207c18 100755 (executable)
@@ -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"
index 2fa6b35..fbf563f 100755 (executable)
@@ -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 \
index 4570e08..59e2a8f 100644 (file)
@@ -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 .*\<acl\>"`" ] && 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
index c04e5ce..339cbb5 100644 (file)
@@ -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
 }
 
 
index 7edf0ba..9c8955d 100644 (file)
@@ -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 \
index f69b313..fd2b407 100755 (executable)
@@ -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():
index 5a00ed7..7e8e41c 100644 (file)
@@ -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         }
 };
index 08a4721..5de7cdf 100644 (file)
@@ -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);
index a6dab8e..8857bb5 100644 (file)
@@ -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",