X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Frcfs%2Fmagic.c;h=1cada33e5bc215e777c40544b4e0563218bb0d98;hb=44c40f29869a02dd430beb7fed0b6ca7d8ef5e54;hp=8a811cbafaeed00d33ab3dd2ebd41692fd5ab25f;hpb=8d40237c730b8be87c1b80a5d96b9c603fefa829;p=linux-2.6.git diff --git a/fs/rcfs/magic.c b/fs/rcfs/magic.c index 8a811cbaf..1cada33e5 100644 --- a/fs/rcfs/magic.c +++ b/fs/rcfs/magic.c @@ -9,19 +9,21 @@ * File operations for common magic files in rcfs, * the user interface for CKRM. * + * * Latest version, more details at http://ckrm.sf.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. + * */ -/* - * Changes +/* Changes * * 23 Apr 2004 * Created from code kept earlier in fs/rcfs/magic_*.c + * */ #include @@ -38,12 +40,12 @@ #include -/* +/****************************************************** * Macros * * generic macros to assist in writing magic fileops * - */ + *****************************************************/ #define MAGIC_SHOW(FUNC) \ static int \ @@ -207,14 +209,16 @@ struct file_operations FUNC ## _fileops = { \ }; \ EXPORT_SYMBOL(FUNC ## _fileops); -/* - * Shared function used by Members / Reclassify - */ +/****************************************************************************** + * Shared function used by Target / Reclassify + * + * + *****************************************************************************/ -#define MEMBERS_MAX_INPUT_SIZE 100 +#define TARGET_MAX_INPUT_SIZE 100 static ssize_t -members_reclassify_write(struct file *file, const char __user * buf, +target_reclassify_write(struct file *file, const char __user * buf, size_t count, loff_t * ppos, int manual) { struct rcfs_inode_info *ri = RCFS_I(file->f_dentry->d_inode); @@ -222,51 +226,77 @@ members_reclassify_write(struct file *file, const char __user * buf, int rc = -EINVAL; ckrm_classtype_t *clstype; - if ((ssize_t) count < 0 || (ssize_t) count > MEMBERS_MAX_INPUT_SIZE) + if ((ssize_t) count < 0 || (ssize_t) count > TARGET_MAX_INPUT_SIZE) return -EINVAL; + if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; + down(&(ri->vfs_inode.i_sem)); - optbuf = kmalloc(MEMBERS_MAX_INPUT_SIZE, GFP_KERNEL); + + optbuf = kmalloc(TARGET_MAX_INPUT_SIZE, GFP_KERNEL); __copy_from_user(optbuf, buf, count); if (optbuf[count - 1] == '\n') optbuf[count - 1] = '\0'; + clstype = ri->core->classtype; if (clstype->forced_reclassify) rc = (*clstype->forced_reclassify) (manual ? ri->core: NULL, optbuf); + up(&(ri->vfs_inode.i_sem)); kfree(optbuf); return (!rc ? count : rc); } -/* +/****************************************************************************** + * Target + * + * pseudo file for manually reclassifying members to a class + * + *****************************************************************************/ + +static ssize_t +target_write(struct file *file, const char __user * buf, + size_t count, loff_t * ppos) +{ + return target_reclassify_write(file,buf,count,ppos,1); +} + +struct file_operations target_fileops = { + .write = target_write, +}; + +EXPORT_SYMBOL(target_fileops); + +/****************************************************************************** * Reclassify * * pseudo file for reclassification of an object through CE - */ + * + *****************************************************************************/ static ssize_t reclassify_write(struct file *file, const char __user * buf, size_t count, loff_t * ppos) { - return members_reclassify_write(file,buf,count,ppos,0); + return target_reclassify_write(file,buf,count,ppos,0); } struct file_operations reclassify_fileops = { .write = reclassify_write, }; -EXPORT_SYMBOL_GPL(reclassify_fileops); +EXPORT_SYMBOL(reclassify_fileops); -/* +/****************************************************************************** * Config * * Set/get configuration parameters of a class. - */ + * + *****************************************************************************/ -/* - * Currently there are no per-class config parameters defined. +/* Currently there are no per-class config parameters defined. * Use existing code as a template */ @@ -289,32 +319,27 @@ MAGIC_CLOSE(config); MAGIC_RDWR_FILEOPS(config); -/* +/****************************************************************************** * Members * * List members of a class - */ + * + *****************************************************************************/ MAGIC_SHOW(members); MAGIC_OPEN(members); MAGIC_CLOSE(members); -static ssize_t -members_write(struct file *file, const char __user * buf, - size_t count, loff_t * ppos) -{ - return members_reclassify_write(file,buf,count,ppos,1); -} - -MAGIC_RDWR_FILEOPS(members); +MAGIC_RD_FILEOPS(members); -/* +/****************************************************************************** * Stats * * Get/reset class statistics * No standard set of stats defined. Each resource controller chooses * its own set of statistics to maintain and export. - */ + * + *****************************************************************************/ #define stats_max_input_size 50 @@ -336,22 +361,21 @@ MAGIC_CLOSE(stats); MAGIC_RDWR_FILEOPS(stats); -/* +/****************************************************************************** * Shares * * Set/get shares of a taskclass. * Share types and semantics are defined by rcfs and ckrm core - */ + * + *****************************************************************************/ #define SHARES_MAX_INPUT_SIZE 300 -/* - * The enums for the share types should match the indices expected by - * array parameter to ckrm_set_resshare - * - * Note only the first NUM_SHAREVAL enums correspond to share types, - * the remaining ones are for token matching purposes - */ +/* The enums for the share types should match the indices expected by + array parameter to ckrm_set_resshare */ + +/* Note only the first NUM_SHAREVAL enums correspond to share types, + the remaining ones are for token matching purposes */ enum share_token_t { MY_GUAR, MY_LIM, TOT_GUAR, MAX_LIM, SHARE_RES_TYPE, SHARE_ERR @@ -375,12 +399,15 @@ shares_parse(char *options, char **resstr, struct ckrm_shares *shares) if (!options) return 1; + while ((p = strsep(&options, ",")) != NULL) { + substring_t args[MAX_OPT_ARGS]; int token; if (!*p) continue; + token = match_token(p, shares_tokens, args); switch (token) { case SHARE_RES_TYPE: @@ -409,6 +436,7 @@ shares_parse(char *options, char **resstr, struct ckrm_shares *shares) default: return 0; } + } return 1; } @@ -433,31 +461,40 @@ shares_write(struct file *file, const char __user * buf, CKRM_SHARE_UNCHANGED, CKRM_SHARE_UNCHANGED }; + if ((ssize_t) count < 0 || (ssize_t) count > SHARES_MAX_INPUT_SIZE) return -EINVAL; + if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; + ri = RCFS_I(file->f_dentry->d_parent->d_inode); + if (!ri || !ckrm_is_core_valid((ckrm_core_class_t *) (ri->core))) { printk(KERN_ERR "shares_write: Error accessing core class\n"); return -EFAULT; } + down(&inode->i_sem); + core = ri->core; optbuf = kmalloc(SHARES_MAX_INPUT_SIZE, GFP_KERNEL); if (!optbuf) { up(&inode->i_sem); return -ENOMEM; } + __copy_from_user(optbuf, buf, count); if (optbuf[count - 1] == '\n') optbuf[count - 1] = '\0'; + done = shares_parse(optbuf, &resname, &newshares); if (!done) { printk(KERN_ERR "Error parsing shares\n"); rc = -EINVAL; goto write_out; } + if (core->classtype->set_shares) { rc = (*core->classtype->set_shares) (core, resname, &newshares); if (rc) { @@ -466,14 +503,17 @@ shares_write(struct file *file, const char __user * buf, goto write_out; } } - printk(KERN_ERR "Set %s shares to %d %d %d %d\n", + + printk(KERN_DEBUG "Set %s shares to %d %d %d %d\n", resname, newshares.my_guarantee, newshares.my_limit, newshares.total_guarantee, newshares.max_limit); + rc = count; -write_out: + write_out: + up(&inode->i_sem); kfree(optbuf); kfree(resname); @@ -488,6 +528,7 @@ MAGIC_RDWR_FILEOPS(shares); /* * magic file creation/deletion + * */ int rcfs_clear_magic(struct dentry *parent) @@ -495,16 +536,20 @@ int rcfs_clear_magic(struct dentry *parent) struct dentry *mftmp, *mfdentry; list_for_each_entry_safe(mfdentry, mftmp, &parent->d_subdirs, d_child) { + if (!rcfs_is_magic(mfdentry)) continue; + if (rcfs_delete_internal(mfdentry)) printk(KERN_ERR "rcfs_clear_magic: error deleting one\n"); } + return 0; + } -EXPORT_SYMBOL_GPL(rcfs_clear_magic); +EXPORT_SYMBOL(rcfs_clear_magic); int rcfs_create_magic(struct dentry *parent, struct rcfs_magf magf[], int count) { @@ -527,4 +572,4 @@ int rcfs_create_magic(struct dentry *parent, struct rcfs_magf magf[], int count) return 0; } -EXPORT_SYMBOL_GPL(rcfs_create_magic); +EXPORT_SYMBOL(rcfs_create_magic);