Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion drivers/staging/lustre/include/linux/libcfs/curproc.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ int cfs_curproc_groups_nr(void);
int current_is_32bit(void);
#define current_pid() (current->pid)
#define current_comm() (current->comm)
int cfs_get_environ(const char *key, char *value, int *val_len);

typedef __u32 cfs_cap_t;

Expand Down
2 changes: 1 addition & 1 deletion drivers/staging/lustre/lustre/Kconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
config LUSTRE_FS
tristate "Lustre file system client support"
depends on INET && m && !MIPS && !XTENSA && !SUPERH
depends on INET && m
select LNET
select CRYPTO
select CRYPTO_CRC32
Expand Down
150 changes: 0 additions & 150 deletions drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,156 +152,6 @@ int current_is_32bit(void)
return is_compat_task();
}

static int cfs_access_process_vm(struct task_struct *tsk, unsigned long addr,
void *buf, int len, int write)
{
/* Just copied from kernel for the kernels which doesn't
* have access_process_vm() exported */
struct mm_struct *mm;
struct vm_area_struct *vma;
struct page *page;
void *old_buf = buf;

mm = get_task_mm(tsk);
if (!mm)
return 0;

down_read(&mm->mmap_sem);
/* ignore errors, just check how much was sucessfully transfered */
while (len) {
int bytes, rc, offset;
void *maddr;

rc = get_user_pages(tsk, mm, addr, 1,
write, 1, &page, &vma);
if (rc <= 0)
break;

bytes = len;
offset = addr & (PAGE_SIZE-1);
if (bytes > PAGE_SIZE-offset)
bytes = PAGE_SIZE-offset;

maddr = kmap(page);
if (write) {
copy_to_user_page(vma, page, addr,
maddr + offset, buf, bytes);
set_page_dirty_lock(page);
} else {
copy_from_user_page(vma, page, addr,
buf, maddr + offset, bytes);
}
kunmap(page);
page_cache_release(page);
len -= bytes;
buf += bytes;
addr += bytes;
}
up_read(&mm->mmap_sem);
mmput(mm);

return buf - old_buf;
}

/* Read the environment variable of current process specified by @key. */
int cfs_get_environ(const char *key, char *value, int *val_len)
{
struct mm_struct *mm;
char *buffer, *tmp_buf = NULL;
int buf_len = PAGE_CACHE_SIZE;
int key_len = strlen(key);
unsigned long addr;
int rc;

buffer = kmalloc(buf_len, GFP_USER);
if (!buffer)
return -ENOMEM;

mm = get_task_mm(current);
if (!mm) {
kfree(buffer);
return -EINVAL;
}

/* Avoid deadlocks on mmap_sem if called from sys_mmap_pgoff(),
* which is already holding mmap_sem for writes. If some other
* thread gets the write lock in the meantime, this thread will
* block, but at least it won't deadlock on itself. LU-1735 */
if (down_read_trylock(&mm->mmap_sem) == 0)
return -EDEADLK;
up_read(&mm->mmap_sem);

addr = mm->env_start;
while (addr < mm->env_end) {
int this_len, retval, scan_len;
char *env_start, *env_end;

memset(buffer, 0, buf_len);

this_len = min_t(int, mm->env_end - addr, buf_len);
retval = cfs_access_process_vm(current, addr, buffer,
this_len, 0);
if (retval != this_len)
break;

addr += retval;

/* Parse the buffer to find out the specified key/value pair.
* The "key=value" entries are separated by '\0'. */
env_start = buffer;
scan_len = this_len;
while (scan_len) {
char *entry;
int entry_len;

env_end = memscan(env_start, '\0', scan_len);
LASSERT(env_end >= env_start &&
env_end <= env_start + scan_len);

/* The last entry of this buffer cross the buffer
* boundary, reread it in next cycle. */
if (unlikely(env_end - env_start == scan_len)) {
/* This entry is too large to fit in buffer */
if (unlikely(scan_len == this_len)) {
CERROR("Too long env variable.\n");
GOTO(out, rc = -EINVAL);
}
addr -= scan_len;
break;
}

entry = env_start;
entry_len = env_end - env_start;

/* Key length + length of '=' */
if (entry_len > key_len + 1 &&
!memcmp(entry, key, key_len)) {
entry += key_len + 1;
entry_len -= key_len + 1;
/* The 'value' buffer passed in is too small.*/
if (entry_len >= *val_len)
GOTO(out, rc = -EOVERFLOW);

memcpy(value, entry, entry_len);
*val_len = entry_len;
GOTO(out, rc = 0);
}

scan_len -= (env_end - env_start + 1);
env_start = env_end + 1;
}
}
GOTO(out, rc = -ENOENT);

out:
mmput(mm);
kfree((void *)buffer);
if (tmp_buf)
kfree((void *)tmp_buf);
return rc;
}
EXPORT_SYMBOL(cfs_get_environ);

EXPORT_SYMBOL(cfs_curproc_groups_nr);
EXPORT_SYMBOL(cfs_cap_raise);
EXPORT_SYMBOL(cfs_cap_lower);
Expand Down
2 changes: 2 additions & 0 deletions drivers/staging/lustre/lustre/llite/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,8 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
struct cl_io *io;
ssize_t result;

ll_io_set_jobid(env, lli);

restart:
io = ccc_env_thread_io(env);
ll_io_init(io, file, iot == CIT_WRITE);
Expand Down
16 changes: 16 additions & 0 deletions drivers/staging/lustre/lustre/llite/llite_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,7 @@ struct vvp_thread_info {
struct ra_io_arg vti_ria;
struct kiocb vti_kiocb;
struct ll_cl_context vti_io_ctx;
char vti_jobid[JOBSTATS_JOBID_SIZE];
};

static inline struct vvp_thread_info *vvp_env_info(const struct lu_env *env)
Expand All @@ -980,6 +981,21 @@ static inline struct vvp_thread_info *vvp_env_info(const struct lu_env *env)
return info;
}

static inline char *vvp_env_jobid(const struct lu_env *env)
{
return vvp_env_info(env)->vti_jobid;
}

static inline void ll_io_set_jobid(const struct lu_env *env, struct ll_inode_info *lli)
{
char *jobid = vvp_env_jobid(env);

if (jobid[0] == '\0')
lustre_get_jobid(jobid);

memcpy(lli->lli_jobid, jobid, JOBSTATS_JOBID_SIZE);
}

static inline struct vvp_io_args *vvp_env_args(const struct lu_env *env,
enum vvp_io_subtype type)
{
Expand Down
1 change: 1 addition & 0 deletions drivers/staging/lustre/lustre/llite/llite_mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ static int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage,
* while truncate is on-going. */
inode = ccc_object_inode(io->ci_obj);
lli = ll_i2info(inode);
ll_io_set_jobid(env, lli);
down_read(&lli->lli_trunc_sem);

result = cl_io_loop(env, io);
Expand Down
8 changes: 0 additions & 8 deletions drivers/staging/lustre/lustre/llite/vvp_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,6 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj,
result = 0;
if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE) {
size_t count;
struct ll_inode_info *lli = ll_i2info(inode);

count = io->u.ci_rw.crw_count;
/* "If nbyte is 0, read() will return 0 and have no other
Expand All @@ -1128,13 +1127,6 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj,
cio->cui_tot_count = count;
cio->cui_tot_nrsegs = 0;
}
/* for read/write, we store the jobid in the inode, and
* it'll be fetched by osc when building RPC.
*
* it's not accurate if the file is shared by different
* jobs.
*/
lustre_get_jobid(lli->lli_jobid);
} else if (io->ci_type == CIT_SETATTR) {
if (!cl_io_is_trunc(io))
io->ci_lockreq = CILR_MANDATORY;
Expand Down
114 changes: 113 additions & 1 deletion drivers/staging/lustre/lustre/obdclass/class_obd.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,116 @@ EXPORT_SYMBOL(obd_dirty_transit_pages);
char obd_jobid_var[JOBSTATS_JOBID_VAR_MAX_LEN + 1] = JOBSTATS_DISABLE;
EXPORT_SYMBOL(obd_jobid_var);

static char *self_environ_file = "/proc/self/environ";
static int obd_get_environ(const char *key, char *value, int *val_len)
{
struct mm_struct *mm;
struct path path;
struct file *filp = NULL;
int buf_len = PAGE_CACHE_SIZE;
int key_len = strlen(key);
char *buffer = NULL;
loff_t pos = 0;
int rc;

/*
* test mm->mmap_sem to avoid deadlock if this ever gets called from
* mmap code.
*/
mm = get_task_mm(current);
if (!mm)
return -EINVAL;
if (down_read_trylock(&mm->mmap_sem) == 0)
return -EDEADLK;
up_read(&mm->mmap_sem);
mmput(mm);

buffer = kmalloc(buf_len, GFP_NOIO);
if (!buffer)
return -ENOMEM;

rc = kern_path(self_environ_file, LOOKUP_FOLLOW, &path);
if (rc)
goto out;

filp = dentry_open(&path, O_RDONLY, current_cred());
if (IS_ERR(filp)) {
rc = PTR_ERR(filp);
filp = NULL;
goto out;
}

/* loop reading... */
while (1) {
int scan_len, this_len;
char *env_start, *env_end;
rc = kernel_read(filp, pos, buffer, buf_len);
if (rc <= 0)
break;

pos += rc;
/* Parse the buffer to find out the specified key/value pair.
* The "key=value" entries are separated by '\0'. */
env_start = buffer;
scan_len = this_len = rc;
while (scan_len) {
char *entry;
int entry_len;

env_end = memscan(env_start, '\0', scan_len);
LASSERT(env_end >= env_start &&
env_end <= env_start + scan_len);

/* The last entry of this buffer cross the buffer
* boundary, reread it in next cycle. */
if (unlikely(env_end - env_start == scan_len)) {
/* This entry is too large to fit in buffer */
if (unlikely(scan_len == this_len)) {
static bool printed;
rc = -EINVAL;
if (!printed) {
CWARN("Environment variable '%s' too long: rc = %d\n",
key, rc);
printed = true;
}
goto out;
}
pos -= scan_len;
break;
}

entry = env_start;
entry_len = env_end - env_start;

/* Key length + length of '=' */
if (entry_len > key_len + 1 &&
!memcmp(entry, key, key_len)) {
entry += key_len + 1;
entry_len -= key_len + 1;
/* The 'value' buffer passed in is too small.*/
if (entry_len >= *val_len)
GOTO(out, rc = -EOVERFLOW);

memcpy(value, entry, entry_len);
*val_len = entry_len;
rc = 0;
goto out;
}

scan_len -= (env_end - env_start + 1);
env_start = env_end + 1;
}
}
if (rc >= 0)
rc = -ENOENT;
out:
if (filp)
fput(filp);
if (buffer)
kfree(buffer);
return rc;
}

/* Get jobid of current process by reading the environment variable
* stored in between the "env_start" & "env_end" of task struct.
*
Expand Down Expand Up @@ -126,7 +236,7 @@ int lustre_get_jobid(char *jobid)
return 0;
}

rc = cfs_get_environ(obd_jobid_var, jobid, &jobid_len);
rc = obd_get_environ(obd_jobid_var, jobid, &jobid_len);
if (rc) {
if (rc == -EOVERFLOW) {
/* For the PBS_JOBID and LOADL_STEP_ID keys (which are
Expand All @@ -149,6 +259,8 @@ int lustre_get_jobid(char *jobid)
"Get jobid for (%s) failed: rc = %d\n",
obd_jobid_var, rc);
}
} else {
CDEBUG(D_INFO, "Got jobid for (%s) value (%s)\n", obd_jobid_var, jobid);
}
return rc;
}
Expand Down