4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2012, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/lvfs/lvfs_linux.c
38 * Author: Andreas Dilger <adilger@clusterfs.com>
41 #define DEBUG_SUBSYSTEM S_FILTER
44 #include <asm/unistd.h>
45 #include <linux/slab.h>
46 #include <linux/pagemap.h>
47 #include <linux/quotaops.h>
48 #include <linux/libcfs/libcfs.h>
49 #include <linux/module.h>
50 #include <linux/lustre_compat25.h>
54 #include <lustre_lib.h>
56 struct lprocfs_stats
*obd_memory
= NULL
;
57 EXPORT_SYMBOL(obd_memory
);
58 /* refine later and change to seqlock or simlar from libcfs */
60 /* Debugging check only needed during development */
62 # define ASSERT_CTXT_MAGIC(magic) LASSERT((magic) == OBD_RUN_CTXT_MAGIC)
63 # define ASSERT_NOT_KERNEL_CTXT(msg) LASSERTF(!segment_eq(get_fs(), get_ds()),\
65 # define ASSERT_KERNEL_CTXT(msg) LASSERTF(segment_eq(get_fs(), get_ds()), msg)
67 # define ASSERT_CTXT_MAGIC(magic) do {} while (0)
68 # define ASSERT_NOT_KERNEL_CTXT(msg) do {} while (0)
69 # define ASSERT_KERNEL_CTXT(msg) do {} while (0)
72 static void push_group_info(struct lvfs_run_ctxt
*save
,
73 struct group_info
*ginfo
)
76 save
->ngroups
= current_ngroups
;
81 save
->group_info
= current_cred()->group_info
;
82 cred
= prepare_creds();
84 cred
->group_info
= ginfo
;
91 static void pop_group_info(struct lvfs_run_ctxt
*save
,
92 struct group_info
*ginfo
)
95 current_ngroups
= save
->ngroups
;
99 cred
= prepare_creds();
101 cred
->group_info
= save
->group_info
;
104 task_unlock(current
);
108 /* push / pop to root of obd store */
109 void push_ctxt(struct lvfs_run_ctxt
*save
, struct lvfs_run_ctxt
*new_ctx
,
110 struct lvfs_ucred
*uc
)
112 /* if there is underlaying dt_device then push_ctxt is not needed */
113 if (new_ctx
->dt
!= NULL
)
116 /* ASSERT_NOT_KERNEL_CTXT("already in kernel context!\n"); */
117 ASSERT_CTXT_MAGIC(new_ctx
->magic
);
118 OBD_SET_CTXT_MAGIC(save
);
121 LASSERT(d_count(cfs_fs_pwd(current
->fs
)));
122 LASSERT(d_count(new_ctx
->pwd
));
123 save
->pwd
= dget(cfs_fs_pwd(current
->fs
));
124 save
->pwdmnt
= mntget(cfs_fs_mnt(current
->fs
));
125 save
->luc
.luc_umask
= current_umask();
126 save
->ngroups
= current_cred()->group_info
->ngroups
;
129 LASSERT(save
->pwdmnt
);
130 LASSERT(new_ctx
->pwd
);
131 LASSERT(new_ctx
->pwdmnt
);
135 save
->luc
.luc_uid
= current_uid();
136 save
->luc
.luc_gid
= current_gid();
137 save
->luc
.luc_fsuid
= current_fsuid();
138 save
->luc
.luc_fsgid
= current_fsgid();
139 save
->luc
.luc_cap
= current_cap();
141 cred
= prepare_creds();
143 cred
->uid
= uc
->luc_uid
;
144 cred
->gid
= uc
->luc_gid
;
145 cred
->fsuid
= uc
->luc_fsuid
;
146 cred
->fsgid
= uc
->luc_fsgid
;
147 cred
->cap_effective
= uc
->luc_cap
;
151 push_group_info(save
,
153 uc
->luc_identity
? uc
->luc_identity
->mi_ginfo
:
156 current
->fs
->umask
= 0; /* umask already applied on client */
158 ll_set_fs_pwd(current
->fs
, new_ctx
->pwdmnt
, new_ctx
->pwd
);
160 EXPORT_SYMBOL(push_ctxt
);
162 void pop_ctxt(struct lvfs_run_ctxt
*saved
, struct lvfs_run_ctxt
*new_ctx
,
163 struct lvfs_ucred
*uc
)
165 /* if there is underlaying dt_device then pop_ctxt is not needed */
166 if (new_ctx
->dt
!= NULL
)
169 ASSERT_CTXT_MAGIC(saved
->magic
);
170 ASSERT_KERNEL_CTXT("popping non-kernel context!\n");
172 LASSERTF(cfs_fs_pwd(current
->fs
) == new_ctx
->pwd
, "%p != %p\n",
173 cfs_fs_pwd(current
->fs
), new_ctx
->pwd
);
174 LASSERTF(cfs_fs_mnt(current
->fs
) == new_ctx
->pwdmnt
, "%p != %p\n",
175 cfs_fs_mnt(current
->fs
), new_ctx
->pwdmnt
);
178 ll_set_fs_pwd(current
->fs
, saved
->pwdmnt
, saved
->pwd
);
181 mntput(saved
->pwdmnt
);
182 current
->fs
->umask
= saved
->luc
.luc_umask
;
185 cred
= prepare_creds();
187 cred
->uid
= saved
->luc
.luc_uid
;
188 cred
->gid
= saved
->luc
.luc_gid
;
189 cred
->fsuid
= saved
->luc
.luc_fsuid
;
190 cred
->fsgid
= saved
->luc
.luc_fsgid
;
191 cred
->cap_effective
= saved
->luc
.luc_cap
;
195 pop_group_info(saved
,
197 uc
->luc_identity
? uc
->luc_identity
->mi_ginfo
:
201 EXPORT_SYMBOL(pop_ctxt
);
203 /* utility to rename a file */
204 int lustre_rename(struct dentry
*dir
, struct vfsmount
*mnt
,
205 char *oldname
, char *newname
)
207 struct dentry
*dchild_old
, *dchild_new
;
210 ASSERT_KERNEL_CTXT("kernel doing rename outside kernel context\n");
211 CDEBUG(D_INODE
, "renaming file %.*s to %.*s\n",
212 (int)strlen(oldname
), oldname
, (int)strlen(newname
), newname
);
214 dchild_old
= ll_lookup_one_len(oldname
, dir
, strlen(oldname
));
215 if (IS_ERR(dchild_old
))
216 return PTR_ERR(dchild_old
);
218 if (!dchild_old
->d_inode
)
219 GOTO(put_old
, err
= -ENOENT
);
221 dchild_new
= ll_lookup_one_len(newname
, dir
, strlen(newname
));
222 if (IS_ERR(dchild_new
))
223 GOTO(put_old
, err
= PTR_ERR(dchild_new
));
225 err
= ll_vfs_rename(dir
->d_inode
, dchild_old
, mnt
,
226 dir
->d_inode
, dchild_new
, mnt
, NULL
);
233 EXPORT_SYMBOL(lustre_rename
);
235 /* Note: dput(dchild) will *not* be called if there is an error */
236 struct l_file
*l_dentry_open(struct lvfs_run_ctxt
*ctxt
, struct l_dentry
*de
,
243 return dentry_open(&path
, flags
, current_cred());
245 EXPORT_SYMBOL(l_dentry_open
);
248 __s64
lprocfs_read_helper(struct lprocfs_counter
*lc
,
249 struct lprocfs_counter_header
*header
,
250 enum lprocfs_stats_flags flags
,
251 enum lprocfs_fields_flags field
)
255 if (lc
== NULL
|| header
== NULL
)
259 case LPROCFS_FIELDS_FLAGS_CONFIG
:
260 ret
= header
->lc_config
;
262 case LPROCFS_FIELDS_FLAGS_SUM
:
264 if ((flags
& LPROCFS_STATS_FLAG_IRQ_SAFE
) != 0)
265 ret
+= lc
->lc_sum_irq
;
267 case LPROCFS_FIELDS_FLAGS_MIN
:
270 case LPROCFS_FIELDS_FLAGS_MAX
:
273 case LPROCFS_FIELDS_FLAGS_AVG
:
274 ret
= (lc
->lc_max
- lc
->lc_min
) / 2;
276 case LPROCFS_FIELDS_FLAGS_SUMSQUARE
:
277 ret
= lc
->lc_sumsquare
;
279 case LPROCFS_FIELDS_FLAGS_COUNT
:
288 EXPORT_SYMBOL(lprocfs_read_helper
);
291 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
292 MODULE_DESCRIPTION("Lustre VFS Filesystem Helper v0.1");
293 MODULE_LICENSE("GPL");