Whamcloud - gitweb
LU-2675 obd: decruft md_enqueue() and md_intent_lock()
[fs/lustre-release.git] / lustre / llite / file.c
index 99dc465..2450897 100644 (file)
@@ -45,6 +45,7 @@
 #include <lustre_lite.h>
 #include <linux/pagemap.h>
 #include <linux/file.h>
+#include <linux/sched.h>
 #include "llite_internal.h"
 #include <lustre/ll_fiemap.h>
 #include <lustre_ioctl.h>
@@ -416,7 +417,7 @@ static int ll_intent_file_open(struct file *file, void *lmm,
         const char *name = file->f_dentry->d_name.name;
         const int len = file->f_dentry->d_name.len;
         struct md_op_data *op_data;
-        struct ptlrpc_request *req;
+       struct ptlrpc_request *req = NULL;
         __u32 opc = LUSTRE_OPC_ANY;
         int rc;
         ENTRY;
@@ -445,9 +446,12 @@ static int ll_intent_file_open(struct file *file, void *lmm,
         if (IS_ERR(op_data))
                 RETURN(PTR_ERR(op_data));
 
+       op_data->op_data = lmm;
+       op_data->op_data_size = lmmsize;
+
        itp->it_flags |= MDS_OPEN_BY_FID;
-        rc = md_intent_lock(sbi->ll_md_exp, op_data, lmm, lmmsize, itp,
-                            0 /*unused */, &req, ll_md_blocking_ast, 0);
+       rc = md_intent_lock(sbi->ll_md_exp, op_data, itp, &req,
+                           &ll_md_blocking_ast, 0);
         ll_finish_md_op_data(op_data);
         if (rc == -ESTALE) {
                 /* reason for keep own exit path - don`t flood log
@@ -775,7 +779,7 @@ ll_lease_open(struct inode *inode, struct file *file, fmode_t fmode,
        struct lookup_intent it = { .it_op = IT_OPEN };
        struct ll_sb_info *sbi = ll_i2sbi(inode);
        struct md_op_data *op_data;
-       struct ptlrpc_request *req;
+       struct ptlrpc_request *req = NULL;
        struct lustre_handle old_handle = { 0 };
        struct obd_client_handle *och = NULL;
        int rc;
@@ -841,15 +845,15 @@ ll_lease_open(struct inode *inode, struct file *file, fmode_t fmode,
 
        it.it_flags = fmode | open_flags;
        it.it_flags |= MDS_OPEN_LOCK | MDS_OPEN_BY_FID | MDS_OPEN_LEASE;
-       rc = md_intent_lock(sbi->ll_md_exp, op_data, NULL, 0, &it, 0, &req,
-                               ll_md_blocking_lease_ast,
+       rc = md_intent_lock(sbi->ll_md_exp, op_data, &it, &req,
+                           &ll_md_blocking_lease_ast,
        /* LDLM_FL_NO_LRU: To not put the lease lock into LRU list, otherwise
         * it can be cancelled which may mislead applications that the lease is
         * broken;
         * LDLM_FL_EXCL: Set this flag so that it won't be matched by normal
         * open in ll_md_blocking_ast(). Otherwise as ll_md_blocking_lease_ast
         * doesn't deal with openhandle, so normal openhandle will be leaked. */
-                               LDLM_FL_NO_LRU | LDLM_FL_EXCL);
+                           LDLM_FL_NO_LRU | LDLM_FL_EXCL);
        ll_finish_md_op_data(op_data);
        ptlrpc_req_finished(req);
        if (rc < 0)
@@ -2990,8 +2994,8 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
               flock.l_flock.pid, flags, einfo.ei_mode,
               flock.l_flock.start, flock.l_flock.end);
 
-        rc = md_enqueue(sbi->ll_md_exp, &einfo, NULL,
-                        op_data, &lockh, &flock, 0, NULL /* req */, flags);
+       rc = md_enqueue(sbi->ll_md_exp, &einfo, &flock, NULL, op_data, &lockh,
+                       flags);
 
        /* Restore the file lock type if not TEST lock. */
        if (!(flags & LDLM_FL_TEST_LOCK))
@@ -3007,8 +3011,8 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
 
        if (rc2 && file_lock->fl_type != F_UNLCK) {
                einfo.ei_mode = LCK_NL;
-               md_enqueue(sbi->ll_md_exp, &einfo, NULL,
-                       op_data, &lockh, &flock, 0, NULL /* req */, flags);
+               md_enqueue(sbi->ll_md_exp, &einfo, &flock, NULL, op_data,
+                          &lockh, flags);
                rc = rc2;
        }
 
@@ -3253,11 +3257,8 @@ static int __ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
                         RETURN(PTR_ERR(op_data));
 
                 oit.it_create_mode |= M_CHECK_STALE;
-                rc = md_intent_lock(exp, op_data, NULL, 0,
-                                    /* we are not interested in name
-                                       based lookup */
-                                    &oit, 0, &req,
-                                    ll_md_blocking_ast, 0);
+               rc = md_intent_lock(exp, op_data, &oit, &req,
+                                   &ll_md_blocking_ast, 0);
                 ll_finish_md_op_data(op_data);
                 oit.it_create_mode &= ~M_CHECK_STALE;
                 if (rc < 0) {
@@ -3507,8 +3508,14 @@ int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
 # endif
 #endif
 {
-        int rc = 0;
-        ENTRY;
+       int rc = 0;
+       struct ll_sb_info *sbi;
+       struct root_squash_info *squash;
+       struct cred *cred = NULL;
+       const struct cred *old_cred = NULL;
+       cfs_cap_t cap;
+       bool squash_id = false;
+       ENTRY;
 
 #ifdef MAY_NOT_BLOCK
        if (mask & MAY_NOT_BLOCK)
@@ -3531,11 +3538,46 @@ int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
        CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), inode mode %x mask %o\n",
               PFID(ll_inode2fid(inode)), inode, inode->i_mode, mask);
 
-       if (ll_i2sbi(inode)->ll_flags & LL_SBI_RMT_CLIENT)
-               return lustre_check_remote_perm(inode, mask);
+       /* squash fsuid/fsgid if needed */
+       sbi = ll_i2sbi(inode);
+       squash = &sbi->ll_squash;
+       if (unlikely(squash->rsi_uid != 0 &&
+                    current_fsuid() == 0 &&
+                    !(sbi->ll_flags & LL_SBI_NOROOTSQUASH))) {
+                       squash_id = true;
+       }
+       if (squash_id) {
+               CDEBUG(D_OTHER, "squash creds (%d:%d)=>(%d:%d)\n",
+                      current_fsuid(), current_fsgid(),
+                      squash->rsi_uid, squash->rsi_gid);
+
+               /* update current process's credentials
+                * and FS capability */
+               cred = prepare_creds();
+               if (cred == NULL)
+                       RETURN(-ENOMEM);
 
-       ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_INODE_PERM, 1);
-       rc = ll_generic_permission(inode, mask, flags, ll_check_acl);
+               cred->fsuid = squash->rsi_uid;
+               cred->fsgid = squash->rsi_gid;
+               for (cap = 0; cap < sizeof(cfs_cap_t) * 8; cap++) {
+                       if ((1 << cap) & CFS_CAP_FS_MASK)
+                               cap_lower(cred->cap_effective, cap);
+               }
+               old_cred = override_creds(cred);
+       }
+
+       ll_stats_ops_tally(sbi, LPROC_LL_INODE_PERM, 1);
+
+       if (sbi->ll_flags & LL_SBI_RMT_CLIENT)
+               rc = lustre_check_remote_perm(inode, mask);
+       else
+               rc = ll_generic_permission(inode, mask, flags, ll_check_acl);
+
+       /* restore current process's credentials and FS capability */
+       if (squash_id) {
+               revert_creds(old_cred);
+               put_cred(cred);
+       }
 
        RETURN(rc);
 }
@@ -3956,8 +3998,8 @@ int ll_layout_refresh(struct inode *inode, __u32 *gen)
        struct ldlm_enqueue_info einfo = {
                .ei_type = LDLM_IBITS,
                .ei_mode = LCK_CR,
-               .ei_cb_bl = ll_md_blocking_ast,
-               .ei_cb_cp = ldlm_completion_ast,
+               .ei_cb_bl = &ll_md_blocking_ast,
+               .ei_cb_cp = &ldlm_completion_ast,
        };
        int rc;
        ENTRY;
@@ -4003,8 +4045,7 @@ again:
                          ll_get_fsname(inode->i_sb, NULL, 0),
                          PFID(&lli->lli_fid), inode);
 
-       rc = md_enqueue(sbi->ll_md_exp, &einfo, &it, op_data, &lockh,
-                       NULL, 0, NULL, 0);
+       rc = md_enqueue(sbi->ll_md_exp, &einfo, NULL, &it, op_data, &lockh, 0);
        if (it.d.lustre.it_data != NULL)
                ptlrpc_req_finished(it.d.lustre.it_data);
        it.d.lustre.it_data = NULL;