Whamcloud - gitweb
LU-4017 quota: add setting/getting project id function 02/26202/13
authorWang Shilong <wshilong@ddn.com>
Mon, 27 Mar 2017 05:43:30 +0000 (13:43 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 13 Apr 2017 18:50:23 +0000 (18:50 +0000)
Extend Attr RPC to support project ID attribute, new
ioctl is introduced to get/set project id, it is kept
same ioctl number as VFS, you could use:

lsattr -p <file>
chattr -p <file>

Redefine LL_MAXQUOTAS as 3, change
@qsd_acct_failed into qqi, otherwise osd-zfs
could not use USR/GRP quota normally.

Remove osd_quota_migration(), it only output
some messages in case upgrading from 1.8 which
give us extra efforts for project quota, remove
it indead.

also fix a typo bug in osp_attr_set().

Change-Id: I4b537be9efa29fda730592b6d5e41c6b60fb6c0d
Signed-off-by: Wang Shilong <wshilong@ddn.com>
Reviewed-on: https://review.whamcloud.com/26202
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
Tested-by: Oleg Drokin <oleg.drokin@intel.com>
30 files changed:
lustre/contrib/wireshark/packet-lustre.c
lustre/include/cl_object.h
lustre/include/lustre/lustre_idl.h
lustre/include/lustre/lustre_user.h
lustre/include/lustre/lustreapi.h
lustre/include/lustre_quota.h
lustre/include/obd.h
lustre/llite/dir.c
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/vvp_object.c
lustre/mdc/mdc_lib.c
lustre/mdt/mdt_lib.c
lustre/osc/osc_cache.c
lustre/osc/osc_request.c
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-ldiskfs/osd_internal.h
lustre/osd-ldiskfs/osd_quota.c
lustre/osp/osp_object.c
lustre/ptlrpc/wiretest.c
lustre/quota/qsd_config.c
lustre/quota/qsd_handler.c
lustre/quota/qsd_internal.h
lustre/quota/qsd_lib.c
lustre/quota/qsd_reint.c
lustre/quota/qsd_writeback.c
lustre/tests/sanity-quota.sh
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index bfd2b6c..65ca314 100644 (file)
@@ -549,7 +549,7 @@ static int hf_lustre_mdt_rec_setattr_sa_ctime = -1;
 static int hf_lustre_mdt_rec_setattr_sa_attr_flags = -1;
 static int hf_lustre_mdt_rec_setattr_sa_mode = -1;
 static int hf_lustre_mdt_rec_setattr_sa_padding_2 = -1;
-static int hf_lustre_mdt_rec_setattr_sa_padding_3 = -1;
+static int hf_lustre_mdt_rec_setattr_sa_projid = -1;
 static int hf_lustre_mdt_rec_setattr_sa_padding_4 = -1;
 static int hf_lustre_mdt_rec_setattr_sa_padding_5 = -1;
 
@@ -3198,7 +3198,7 @@ lustre_dissect_struct_mdt_body(tvbuff_t *tvb _U_, int offset _U_,
 /* IDL:        uint32 sa_attr_flags; */
 /* IDL:        uint32 sa_mode; */
 /* IDL:        uint32 sa_padding_2; */
-/* IDL:        uint32 sa_padding_3; */
+/* IDL:        uint32 sa_projid; */
 /* IDL:        uint32 sa_padding_4; */
 /* IDL:        uint32 sa_padding_5; */
 /* IDL: } */
@@ -3393,9 +3393,9 @@ lustre_dissect_element_mdt_rec_setattr_sa_padding_2(tvbuff_t *tvb _U_, int offse
 }
 
 static int
-lustre_dissect_element_mdt_rec_setattr_sa_padding_3(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_)
+lustre_dissect_element_mdt_rec_setattr_sa_projid(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_)
 {
-  offset=dissect_uint32(tvb, offset, pinfo, tree,  hf_lustre_mdt_rec_setattr_sa_padding_3);
+  offset=dissect_uint32(tvb, offset, pinfo, tree,  hf_lustre_mdt_rec_setattr_sa_projid);
 
   return offset;
 }
@@ -3479,7 +3479,7 @@ lustre_dissect_struct_mdt_rec_setattr(tvbuff_t *tvb _U_, int offset _U_, packet_
 
   offset=lustre_dissect_element_mdt_rec_setattr_sa_padding_2(tvb, offset, pinfo, tree);
 
-  offset=lustre_dissect_element_mdt_rec_setattr_sa_padding_3(tvb, offset, pinfo, tree);
+  offset=lustre_dissect_element_mdt_rec_setattr_sa_projid(tvb, offset, pinfo, tree);
 
   offset=lustre_dissect_element_mdt_rec_setattr_sa_padding_4(tvb, offset, pinfo, tree);
 
@@ -9909,8 +9909,8 @@ void proto_register_dcerpc_lustre(void)
       { "Sa Mode", "lustre.mdt_rec_setattr.sa_mode", FT_UINT32, BASE_OCT, NULL, 0, "", HFILL }},
     { &hf_lustre_mdt_rec_setattr_sa_padding_2,
       { "Sa Padding 2", "lustre.mdt_rec_setattr.sa_padding_2", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }},
-    { &hf_lustre_mdt_rec_setattr_sa_padding_3,
-      { "Sa Padding 3", "lustre.mdt_rec_setattr.sa_padding_3", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }},
+    { &hf_lustre_mdt_rec_setattr_sa_projid,
+      { "Sa Padding 3", "lustre.mdt_rec_setattr.sa_projid", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }},
     { &hf_lustre_mdt_rec_setattr_sa_padding_4,
       { "Sa Padding 4", "lustre.mdt_rec_setattr.sa_padding_4", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }},
     { &hf_lustre_mdt_rec_setattr_sa_padding_5,
index 655e6b1..dba3ef3 100644 (file)
@@ -166,6 +166,9 @@ struct cl_attr {
 
        /* nlink of the directory */
        __u64  cat_nlink;
+
+       /* Project identifier for quota purpose. */
+       __u32  cat_projid;
 };
 
 /**
@@ -179,7 +182,8 @@ enum cl_attr_valid {
         CAT_CTIME  = 1 << 5,
         CAT_BLOCKS = 1 << 6,
         CAT_UID    = 1 << 7,
-        CAT_GID    = 1 << 8
+       CAT_GID    = 1 << 8,
+       CAT_PROJID = 1 << 9
 };
 
 /**
index 12a9251..3afa428 100644 (file)
@@ -1744,7 +1744,7 @@ struct mdt_rec_setattr {
         __u32           sa_attr_flags;
         __u32           sa_mode;
        __u32           sa_bias;      /* some operation flags */
-        __u32           sa_padding_3;
+       __u32           sa_projid;
         __u32           sa_padding_4;
         __u32           sa_padding_5;
 };
index 71d5814..eb90190 100644 (file)
@@ -65,7 +65,7 @@
  * Should be removed as soon as system header is updated.
  */
 #undef LL_MAXQUOTAS
-#define LL_MAXQUOTAS 2
+#define LL_MAXQUOTAS 3
 #undef INITQFNAMES
 #define INITQFNAMES { \
     "user",    /* USRQUOTA */ \
@@ -362,6 +362,25 @@ struct ll_futimes_3 {
 #define LL_IOC_GETPARENT               _IOWR('f', 249, struct getparent)
 #define LL_IOC_LADVISE                 _IOR('f', 250, struct llapi_lu_ladvise)
 
+#ifdef FS_IOC_FSGETXATTR
+#define LL_IOC_FSGETXATTR              FS_IOC_FSGETXATTR
+#define LL_IOC_FSSETXATTR              FS_IOC_FSSETXATTR
+#else
+/*
+ * Structure for FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR.
+*/
+struct fsxattr {
+       __u32           fsx_xflags;     /* xflags field value (get/set) */
+       __u32           fsx_extsize;    /* extsize field value (get/set)*/
+       __u32           fsx_nextents;   /* nextents field value (get)   */
+       __u32           fsx_projid;     /* project identifier (get/set) */
+       unsigned char   fsx_pad[12];
+};
+#define LL_IOC_FSGETXATTR              _IOR('X', 31, struct fsxattr)
+#define LL_IOC_FSSETXATTR              _IOW('X', 32, struct fsxattr)
+#endif
+
+
 /* Lease types for use as arg and return of LL_IOC_{GET,SET}_LEASE ioctl. */
 enum ll_lease_type {
        LL_LEASE_RDLCK  = 0x1,
index e8d895a..886409d 100644 (file)
@@ -43,7 +43,7 @@
 #include <lustre/lustre_user.h>
 
 #ifndef LL_MAXQUOTAS
-#define LL_MAXQUOTAS 2
+#define LL_MAXQUOTAS 3
 #endif
 
 extern bool liblustreapi_initialized;
index 1a2f2a3..ab28b24 100644 (file)
@@ -48,7 +48,7 @@
 #endif
 
 #ifndef LL_MAXQUOTAS
-#define LL_MAXQUOTAS 2
+#define LL_MAXQUOTAS 3
 #endif
 
 struct lquota_id_info;
index 868a7aa..afeaed8 100644 (file)
@@ -836,6 +836,7 @@ struct md_op_data {
 
        /* default stripe offset */
        __u32                   op_default_stripe_offset;
+       __u32                   op_projid;
 };
 
 struct md_callback {
index c6a59cd..578e610 100644 (file)
@@ -1756,6 +1756,9 @@ migrate_free:
 
                RETURN(rc);
        }
+       case LL_IOC_FSGETXATTR:
+       case LL_IOC_FSSETXATTR:
+               RETURN(ll_ioctl_projid(inode, cmd, arg));
        default:
                RETURN(obd_iocontrol(cmd, sbi->ll_dt_exp, 0, NULL,
                                     (void __user *)arg));
index 68ac435..180f288 100644 (file)
@@ -2338,6 +2338,73 @@ static int ll_ladvise(struct inode *inode, struct file *file, __u64 flags,
        RETURN(rc);
 }
 
+int ll_ioctl_projid(struct inode *inode, unsigned int cmd,
+                   unsigned long arg)
+{
+       int rc = 0;
+       struct fsxattr *fsxattr;
+       int alloc_size = sizeof(*fsxattr);
+
+       switch (cmd) {
+       case LL_IOC_FSGETXATTR: {
+               OBD_ALLOC_PTR(fsxattr);
+               if (fsxattr == NULL)
+                       RETURN(-ENOMEM);
+
+               if (copy_from_user(fsxattr,
+                                  (const struct fsxattr __user *)arg,
+                                  alloc_size))
+                       GOTO(out_fsxattr, rc = -EFAULT);
+
+               fsxattr->fsx_projid = ll_i2info(inode)->lli_projid;
+               if (copy_to_user((struct fsxattr __user *)arg,
+                                fsxattr, alloc_size))
+                       GOTO(out_fsxattr, rc = -EFAULT);
+out_fsxattr:
+               OBD_FREE(fsxattr, alloc_size);
+               RETURN(rc);
+       }
+
+       case LL_IOC_FSSETXATTR: {
+               struct md_op_data *op_data;
+               struct ptlrpc_request *req = NULL;
+
+               /* only root could change project ID */
+               if (!cfs_capable(CFS_CAP_SYS_ADMIN))
+                       RETURN(-EPERM);
+
+               op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
+                                            LUSTRE_OPC_ANY, NULL);
+               if (IS_ERR(op_data))
+                       RETURN(PTR_ERR(op_data));
+
+               OBD_ALLOC_PTR(fsxattr);
+               if (fsxattr == NULL)
+                       GOTO(out_fsxattr1, rc = -ENOMEM);
+
+               if (copy_from_user(fsxattr,
+                                  (const struct fsxattr __user *)arg,
+                                  alloc_size))
+                       GOTO(out_fsxattr1, rc = -EFAULT);
+
+               op_data->op_projid = fsxattr->fsx_projid;
+               op_data->op_attr.ia_valid |= MDS_ATTR_PROJID;
+               rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, op_data, NULL,
+                               0, &req);
+               ptlrpc_req_finished(req);
+
+out_fsxattr1:
+               ll_finish_md_op_data(op_data);
+               OBD_FREE(fsxattr, alloc_size);
+               RETURN(rc);
+       }
+       default:
+               LASSERT(0);
+       }
+
+       RETURN(rc);
+}
+
 static long
 ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
@@ -2733,6 +2800,9 @@ out_ladvise:
                OBD_FREE(ladvise_hdr, alloc_size);
                RETURN(rc);
        }
+       case LL_IOC_FSGETXATTR:
+       case LL_IOC_FSSETXATTR:
+               RETURN(ll_ioctl_projid(inode, cmd, arg));
        default: {
                int err;
 
index 8aac073..c8432b1 100644 (file)
@@ -816,6 +816,8 @@ int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd);
 int ll_inode_permission(struct inode *inode, int mask);
 # endif
 #endif
+int ll_ioctl_projid(struct inode *inode, unsigned int cmd,
+                   unsigned long arg);
 
 int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file,
                             __u64  flags, struct lov_user_md *lum,
index 5cb81f9..bbf5c3e 100644 (file)
@@ -1675,6 +1675,11 @@ int ll_setattr(struct dentry *de, struct iattr *attr)
            !(attr->ia_valid & ATTR_KILL_SGID))
                attr->ia_valid |= ATTR_KILL_SGID;
 
+       /* avoid polluted from ATTR_TIMES_SET, projid is not
+        * expected to be setted here */
+       if (attr->ia_valid & MDS_ATTR_PROJID)
+               attr->ia_valid &= ~MDS_ATTR_PROJID;
+
        return ll_setattr_raw(de, attr, false);
 }
 
index cc3ea89..8904e45 100644 (file)
@@ -100,6 +100,7 @@ static int vvp_attr_get(const struct lu_env *env, struct cl_object *obj,
        attr->cat_blocks = inode->i_blocks;
        attr->cat_uid = from_kuid(&init_user_ns, inode->i_uid);
        attr->cat_gid = from_kgid(&init_user_ns, inode->i_gid);
+       attr->cat_projid = ll_i2info(inode)->lli_projid;
        /* KMS is not known by this layer */
        return 0; /* layers below have to fill in the rest */
 }
@@ -121,8 +122,10 @@ static int vvp_attr_update(const struct lu_env *env, struct cl_object *obj,
                inode->i_ctime.tv_sec = attr->cat_ctime;
        if (0 && valid & CAT_SIZE)
                i_size_write(inode, attr->cat_size);
+       if (valid & CAT_PROJID)
+               ll_i2info(inode)->lli_projid = attr->cat_projid;
        /* not currently necessary */
-       if (0 && valid & (CAT_UID|CAT_GID|CAT_SIZE))
+       if (0 && valid & (CAT_UID|CAT_GID|CAT_SIZE|CAT_PROJID))
                mark_inode_dirty(inode);
        return 0;
 }
index 3ab2029..5c2acf8 100644 (file)
@@ -318,6 +318,8 @@ static inline __u64 attr_pack(unsigned int ia_valid) {
         if (ia_valid & MDS_OPEN_OWNEROVERRIDE)
                 /* NFSD hack (see bug 5781) */
                 sa_valid |= MDS_OPEN_OWNEROVERRIDE;
+       if (ia_valid & MDS_ATTR_PROJID)
+               sa_valid |= MDS_ATTR_PROJID;
         return sa_valid;
 }
 
@@ -335,6 +337,7 @@ static void mdc_setattr_pack_rec(struct mdt_rec_setattr *rec,
        rec->sa_mode   = op_data->op_attr.ia_mode;
        rec->sa_uid    = from_kuid(&init_user_ns, op_data->op_attr.ia_uid);
        rec->sa_gid    = from_kgid(&init_user_ns, op_data->op_attr.ia_gid);
+       rec->sa_projid = op_data->op_projid;
        rec->sa_size   = op_data->op_attr.ia_size;
        rec->sa_blocks = op_data->op_attr_blocks;
        rec->sa_atime  = LTIME_S(op_data->op_attr.ia_atime);
index 95f16d8..965d73e 100644 (file)
@@ -928,6 +928,7 @@ static int mdt_setattr_unpack_rec(struct mdt_thread_info *info)
                                      NODEMAP_CLIENT_TO_FS, rec->sa_uid);
        la->la_gid   = nodemap_map_id(nodemap, NODEMAP_GID,
                                      NODEMAP_CLIENT_TO_FS, rec->sa_gid);
+       la->la_projid = rec->sa_projid;
        nodemap_putref(nodemap);
 
        la->la_size  = rec->sa_size;
index c417c10..96d13ca 100644 (file)
@@ -2420,6 +2420,7 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io,
 
                qid[USRQUOTA] = attr->cat_uid;
                qid[GRPQUOTA] = attr->cat_gid;
+               qid[PRJQUOTA] = attr->cat_projid;
                if (rc == 0 && osc_quota_chkdq(cli, qid) == NO_QUOTA)
                        rc = -EDQUOT;
                if (rc)
index 114b6ce..d2086a1 100644 (file)
@@ -1384,15 +1384,16 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
                 RETURN(-EPROTO);
         }
 
-        /* set/clear over quota flag for a uid/gid */
+        /* set/clear over quota flag for a uid/gid/projid */
         if (lustre_msg_get_opc(req->rq_reqmsg) == OST_WRITE &&
             body->oa.o_valid & (OBD_MD_FLALLQUOTA)) {
                unsigned qid[LL_MAXQUOTAS] =
-                                       {body->oa.o_uid, body->oa.o_gid};
+                                       { body->oa.o_uid, body->oa.o_gid,
+                                        body->oa.o_projid };
 
-               CDEBUG(D_QUOTA, "setdq for [%u %u] with valid %#llx, flags %x\n",
-                       body->oa.o_uid, body->oa.o_gid, body->oa.o_valid,
-                       body->oa.o_flags);
+               CDEBUG(D_QUOTA, "setdq for [%u %u %u] with valid %#llx, flags %x\n",
+                       body->oa.o_uid, body->oa.o_gid, body->oa.o_projid,
+                      body->oa.o_valid, body->oa.o_flags);
                 osc_quota_setdq(cli, qid, body->oa.o_valid, body->oa.o_flags);
         }
 
index 1bb8fa3..2af1a52 100644 (file)
@@ -1955,6 +1955,9 @@ static void osd_object_delete(const struct lu_env *env, struct lu_object *l)
 
                        qi->lqi_id.qid_uid = gid;
                        qsd_op_adjust(env, qsd, &qi->lqi_id, GRPQUOTA);
+
+                       qi->lqi_id.qid_uid = i_projid_read(inode);
+                       qsd_op_adjust(env, qsd, &qi->lqi_id, PRJQUOTA);
                }
         }
 }
@@ -4352,10 +4355,6 @@ static int osd_index_try(const struct lu_env *env, struct dt_object *dt,
         }
         LINVRNT(osd_invariant(obj));
 
-       if (result == 0 && feat == &dt_quota_glb_features &&
-           fid_seq(lu_object_fid(&dt->do_lu)) == FID_SEQ_QUOTA_GLB)
-               result = osd_quota_migration(env, dt);
-
         return result;
 }
 
index eb7a72e..c495687 100644 (file)
@@ -750,7 +750,6 @@ const struct dt_rec *osd_quota_pack(struct osd_object *obj,
                                    const struct dt_rec *rec,
                                    union lquota_rec *quota_rec);
 void osd_quota_unpack(struct osd_object *obj, const struct dt_rec *rec);
-int osd_quota_migration(const struct lu_env *env, struct dt_object *dt);
 
 #ifndef HAVE_I_UID_READ
 static inline uid_t i_uid_read(const struct inode *inode)
index 4f62122..90e8ad6 100644 (file)
@@ -661,8 +661,8 @@ int osd_declare_inode_qid(const struct lu_env *env, qid_t uid, qid_t gid,
 
        /* and now project quota */
        qi->lqi_id.qid_gid = projid;
-       qi->lqi_type       = PRJQUOTA; /* false now */
-       rcp = osd_declare_qid(env, oh, qi, obj, false, flags);
+       qi->lqi_type       = PRJQUOTA;
+       rcp = osd_declare_qid(env, oh, qi, obj, true, flags);
 
        if (force && (rcp == -EDQUOT || rcp == -EINPROGRESS))
                /* as before, ignore EDQUOT & EINPROGRESS for root */
@@ -677,94 +677,3 @@ int osd_declare_inode_qid(const struct lu_env *env, qid_t uid, qid_t gid,
 
        RETURN(0);
 }
-
-int osd_quota_migration(const struct lu_env *env, struct dt_object *dt)
-{
-       struct osd_thread_info  *oti = osd_oti_get(env);
-       struct osd_device       *osd = osd_obj2dev(osd_dt_obj(dt));
-       struct dt_object        *root, *parent = NULL, *admin = NULL;
-       dt_obj_version_t         version;
-       char                    *fname, *fnames[] = {ADMIN_USR, ADMIN_GRP};
-       int                      rc, i;
-       ENTRY;
-
-       /* not newly created global index */
-       version = dt_version_get(env, dt);
-       if (version != 0)
-               RETURN(0);
-
-       /* locate root */
-       rc = dt_root_get(env, &osd->od_dt_dev, &oti->oti_fid);
-       if (rc) {
-               CERROR("%s: Can't get root FID, rc:%d\n", osd->od_svname, rc);
-               RETURN(rc);
-       }
-
-       root = dt_locate(env, &osd->od_dt_dev, &oti->oti_fid);
-       if (IS_ERR(root)) {
-               CERROR("%s: Failed to locate root "DFID", rc:%ld\n",
-                      osd->od_svname, PFID(&oti->oti_fid), PTR_ERR(root));
-               RETURN(PTR_ERR(root));
-       }
-
-       /* locate /OBJECTS */
-       rc = dt_lookup_dir(env, root, OBJECTS, &oti->oti_fid);
-       if (rc == -ENOENT) {
-               GOTO(out, rc = 0);
-       } else if (rc) {
-               CERROR("%s: Failed to lookup %s, rc:%d\n",
-                      osd->od_svname, OBJECTS, rc);
-               GOTO(out, rc);
-       }
-
-       parent = dt_locate(env, &osd->od_dt_dev, &oti->oti_fid);
-       if (IS_ERR(parent)) {
-               CERROR("%s: Failed to locate %s "DFID", rc:%ld\n",
-                      osd->od_svname, OBJECTS, PFID(&oti->oti_fid),
-                      PTR_ERR(parent));
-               GOTO(out, rc = PTR_ERR(parent));
-       }
-
-       /* locate quota admin files */
-       for (i = 0; i < 2; i++) {
-               fname = fnames[i];
-               rc = dt_lookup_dir(env, parent, fname, &oti->oti_fid);
-               if (rc == -ENOENT) {
-                       rc = 0;
-                       continue;
-               } else if (rc) {
-                       CERROR("%s: Failed to lookup %s, rc:%d\n",
-                              osd->od_svname, fname, rc);
-                       GOTO(out, rc);
-               }
-
-               admin = dt_locate(env, &osd->od_dt_dev, &oti->oti_fid);
-               if (IS_ERR(admin)) {
-                       CERROR("%s: Failed to locate %s "DFID", rc:%d\n",
-                              osd->od_svname, fname, PFID(&oti->oti_fid), rc);
-                       GOTO(out, rc = PTR_ERR(admin));
-               }
-
-               if (!dt_object_exists(admin)) {
-                       CERROR("%s: Old admin file %s doesn't exist, but is "
-                              "still referenced in parent directory.\n",
-                              osd->od_svname, fname);
-                       dt_object_put(env, admin);
-                       GOTO(out, rc = -ENOENT);
-               }
-
-               LCONSOLE_WARN("%s: Detected old quota admin file(%s)! If you "
-                             "want to keep the old quota limits settings, "
-                             "please upgrade to lower version(2.5) first to "
-                             "convert them into new format.\n",
-                             osd->od_svname, fname);
-
-               dt_object_put(env, admin);
-               GOTO(out, rc = -EINVAL);
-       }
-out:
-       if (parent && !IS_ERR(parent))
-               dt_object_put(env, parent);
-       dt_object_put(env, root);
-       RETURN(rc);
-}
index 2145285..fc823e3 100644 (file)
@@ -681,7 +681,7 @@ static int osp_attr_set(const struct lu_env *env, struct dt_object *dt,
                        la->la_valid |= LA_GID;
                }
                if (attr->la_valid & LA_PROJID) {
-                       la->la_gid = attr->la_projid;
+                       la->la_projid = attr->la_projid;
                        la->la_valid |= LA_PROJID;
                }
                spin_unlock(&o->opo_lock);
index 55fda60..00058a9 100644 (file)
@@ -2445,10 +2445,10 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct mdt_rec_setattr, sa_bias));
        LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_bias) == 4, "found %lld\n",
                 (long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_bias));
-       LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_padding_3) == 124, "found %lld\n",
-                (long long)(int)offsetof(struct mdt_rec_setattr, sa_padding_3));
-       LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_3) == 4, "found %lld\n",
-                (long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_3));
+       LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_projid) == 124, "found %lld\n",
+                (long long)(int)offsetof(struct mdt_rec_setattr, sa_projid));
+       LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_projid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_projid));
        LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_padding_4) == 128, "found %lld\n",
                 (long long)(int)offsetof(struct mdt_rec_setattr, sa_padding_4));
        LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_4) == 4, "found %lld\n",
index 06e566e..4fc3a4d 100644 (file)
@@ -187,19 +187,19 @@ int qsd_process_config(struct lustre_cfg *lcfg)
                        read_unlock(&qsd->qsd_lock);
                        if (skip)
                                continue;
-                       if (qsd->qsd_acct_failed) {
-                               LCONSOLE_ERROR("%s: can't enable quota "
-                                              "enforcement since space "
-                                              "accounting isn't functional. "
-                                              "Please run tunefs.lustre "
-                                              "--quota on an unmounted "
-                                              "filesystem if not done already"
-                                              "\n", qsd->qsd_svname);
-                               continue;
-                       }
 
                        for (type = USRQUOTA; type < LL_MAXQUOTAS; type++) {
                                qqi = qsd->qsd_type_array[type];
+                               if (qqi->qqi_acct_failed) {
+                                       LCONSOLE_ERROR("%s: can't enable quota "
+                                                      "enforcement since space "
+                                                      "accounting isn't functional. "
+                                                      "Please run tunefs.lustre "
+                                                      "--quota on an unmounted "
+                                                      "filesystem if not done already"
+                                                      "\n", qsd->qsd_svname);
+                                       continue;
+                               }
                                qsd_start_reint_thread(qqi);
                        }
                }
index b38a111..e2fdd35 100644 (file)
@@ -856,7 +856,7 @@ int qsd_op_begin(const struct lu_env *env, struct qsd_instance *qsd,
         * or - the user/group is root
         * or - quota accounting isn't enabled */
        if (!qsd_type_enabled(qsd, qi->lqi_type) || qi->lqi_id.qid_uid == 0 ||
-           qsd->qsd_acct_failed)
+           (qsd->qsd_type_array[qi->lqi_type])->qqi_acct_failed)
                RETURN(0);
 
        LASSERTF(trans->lqt_id_cnt <= QUOTA_MAX_TRANSIDS, "id_cnt=%d\n",
index 9b1d6b2..488602c 100644 (file)
@@ -107,14 +107,13 @@ struct qsd_instance {
         * enforced here (via procfs) */
        int                      qsd_timeout;
 
-       unsigned long            qsd_is_md:1,    /* managing quota for mdt */
-                                qsd_started:1,  /* instance is now started */
-                                qsd_prepared:1, /* qsd_prepare() successfully
+       unsigned long           qsd_is_md:1,    /* managing quota for mdt */
+                               qsd_started:1,  /* instance is now started */
+                               qsd_prepared:1, /* qsd_prepare() successfully
                                                  * called */
-                                qsd_exp_valid:1,/* qsd_exp is now valid */
-                                qsd_stopping:1, /* qsd_instance is stopping */
-                                qsd_acct_failed:1; /* failed to set up acct
-                                                    * for one quota type */
+                               qsd_exp_valid:1,/* qsd_exp is now valid */
+                               qsd_stopping:1; /* qsd_instance is stopping */
+
 };
 
 /*
@@ -169,11 +168,12 @@ struct qsd_qtype_info {
 
        /* Various flags representing the current state of the slave for this
         * quota type. */
-       unsigned long            qqi_glb_uptodate:1, /* global index uptodate
+       unsigned long           qqi_glb_uptodate:1, /* global index uptodate
                                                        with master */
-                                qqi_slv_uptodate:1, /* slave index uptodate
+                               qqi_slv_uptodate:1, /* slave index uptodate
                                                        with master */
-                                qqi_reint:1;    /* in reintegration or not */
+                               qqi_reint:1,    /* in reintegration or not */
+                               qqi_acct_failed:1; /* failed to setup acct */
 
        /* A list of references to this instance, for debugging */
        struct lu_ref            qqi_reference;
index 1bf6533..7ab8648 100644 (file)
@@ -426,7 +426,7 @@ static int qsd_qtype_init(const struct lu_env *env, struct qsd_instance *qsd,
                       qsd->qsd_svname, qtype_name(qtype),
                       PTR_ERR(qqi->qqi_acct_obj));
                qqi->qqi_acct_obj = NULL;
-               qsd->qsd_acct_failed = true;
+               qqi->qqi_acct_failed = true;
        }
 
        /* open global index copy */
@@ -740,7 +740,8 @@ int qsd_prepare(const struct lu_env *env, struct qsd_instance *qsd)
        for (qtype = USRQUOTA; qtype < LL_MAXQUOTAS; qtype++) {
                struct qsd_qtype_info   *qqi = qsd->qsd_type_array[qtype];
 
-               if (qsd_type_enabled(qsd, qtype) && qsd->qsd_acct_failed) {
+               if (qsd_type_enabled(qsd, qtype) &&
+                   qqi->qqi_acct_failed) {
                        LCONSOLE_ERROR("%s: can't enable quota enforcement "
                                       "since space accounting isn't functional"
                                       ". Please run tunefs.lustre --quota on "
index b355eb8..6e805df 100644 (file)
@@ -638,7 +638,7 @@ int qsd_start_reint_thread(struct qsd_qtype_info *qqi)
        if (!qsd_type_enabled(qsd, qqi->qqi_qtype))
                RETURN(0);
 
-       if (qsd->qsd_acct_failed)
+       if (qqi->qqi_acct_failed)
                /* no space accounting support, can't enable enforcement */
                RETURN(0);
 
index 9b12c2c..628c661 100644 (file)
@@ -388,16 +388,14 @@ static bool qsd_job_pending(struct qsd_instance *qsd, struct list_head *upd,
                job_pending = true;
        }
 
-       if (qsd->qsd_acct_failed) {
-               /* don't bother kicking off reintegration if space accounting
-                * failed to be enabled */
-               write_unlock(&qsd->qsd_lock);
-               return job_pending;
-       }
-
        for (qtype = USRQUOTA; qtype < LL_MAXQUOTAS; qtype++) {
                struct qsd_qtype_info *qqi = qsd->qsd_type_array[qtype];
 
+               /* don't bother kicking off reintegration if space accounting
+                * failed to be enabled */
+               if (qqi->qqi_acct_failed)
+                       continue;
+
                if (!qsd_type_enabled(qsd, qtype))
                        continue;
 
index 439488d..258422d 100755 (executable)
@@ -285,6 +285,40 @@ wait_ost_reint() {
        return 0
 }
 
+enable_project_quota() {
+       stopall || error "failed to stopall (1)"
+
+       for num in $(seq $MDSCOUNT); do
+               do_facet mds$num $TUNE2FS -O project $(mdsdevname $num) ||
+                       error "tune2fs $(mdsdevname $num) failed"
+       done
+
+       for i in $(seq $OSTCOUNT); do
+               do_facet ost$num $TUNE2FS -O project $(ostdevname $num) ||
+                       error "tune2fs $(ostdevname $num) failed"
+       done
+
+       mount
+       setupall
+}
+
+disable_project_quota() {
+       stopall || error "failed to stopall (1)"
+
+       for num in $(seq $MDSCOUNT); do
+               do_facet mds$num $TUNE2FS -Q ^prj $(mdsdevname $num) ||
+                       error "tune2fs $(mdsdevname $num) failed"
+       done
+
+       for i in $(seq $OSTCOUNT); do
+               do_facet ost$num $TUNE2FS -Q ^prj $(ostdevname $num) ||
+                       error "tune2fs $(ostdevname $num) failed"
+       done
+
+       mount
+       setupall
+}
+
 setup_quota_test() {
        wait_delete_completed
        echo "Creating test directory"
@@ -2384,6 +2418,41 @@ test_38() {
 }
 run_test 38 "Quota accounting iterator doesn't skip id entries"
 
+test_39() {
+       [ "$(facet_fstype $singlemds)" != "ldiskfs" ] &&
+               skip "only for ldiskfs mdt" && return 0
+
+       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10) ] &&
+               skip "Old server doesn't support project quota." && return
+
+       man lsattr | grep -i project ||
+               skip "old e2fsprogs dosen't support project quota" &&
+               return 0
+
+       enable_project_quota
+
+       local TESTFILE="$DIR/project"
+       touch $TESTFILE
+       projectid=$(lsattr -p $TESTFILE | awk '{print $1}')
+       [ $projectid -ne 0 ] &&
+               error "Project id should be 0 not $projectid"
+       chattr -p 1024 $TESTFILE
+       projectid=$(lsattr -p $TESTFILE | awk '{print $1}')
+       [ $projectid -ne 1024 ] &&
+               error "Project id should be 1024 not $projectid"
+
+       stopall || error "failed to stopall (1)"
+       mount
+       setupall
+       projectid=$(lsattr -p $TESTFILE | awk '{print $1}')
+       [ $projectid -ne 1024 ] &&
+               error "Project id should be 1024 not $projectid"
+
+       disable_project_quota
+       cleanup_quota_test
+}
+run_test 39 "Project ID interface works correctly"
+
 quota_fini()
 {
        do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=-quota"
index d114d67..46b0571 100644 (file)
@@ -1125,7 +1125,7 @@ check_mdt_rec_setattr(void)
        CHECK_MEMBER(mdt_rec_setattr, sa_attr_flags);
        CHECK_MEMBER(mdt_rec_setattr, sa_mode);
        CHECK_MEMBER(mdt_rec_setattr, sa_bias);
-       CHECK_MEMBER(mdt_rec_setattr, sa_padding_3);
+       CHECK_MEMBER(mdt_rec_setattr, sa_projid);
        CHECK_MEMBER(mdt_rec_setattr, sa_padding_4);
        CHECK_MEMBER(mdt_rec_setattr, sa_padding_5);
 }
index bd26057..172d127 100644 (file)
@@ -2463,10 +2463,10 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct mdt_rec_setattr, sa_bias));
        LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_bias) == 4, "found %lld\n",
                 (long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_bias));
-       LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_padding_3) == 124, "found %lld\n",
-                (long long)(int)offsetof(struct mdt_rec_setattr, sa_padding_3));
-       LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_3) == 4, "found %lld\n",
-                (long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_3));
+       LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_projid) == 124, "found %lld\n",
+                (long long)(int)offsetof(struct mdt_rec_setattr, sa_projid));
+       LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_projid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_projid));
        LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_padding_4) == 128, "found %lld\n",
                 (long long)(int)offsetof(struct mdt_rec_setattr, sa_padding_4));
        LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_4) == 4, "found %lld\n",