diff options
author | Khalid Aziz <khalid.aziz@oracle.com> | 2014-07-18 11:15:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-22 00:37:06 -0400 |
commit | 07d66921337176e9d27e4d0a8a23425c8284a381 (patch) | |
tree | 84880064d92c2f597d0dd5622f7469d96f0372b3 /arch/sparc | |
parent | e7fbaf016e917a14b5cbed7a724e0a45338700ee (diff) |
sparc: Add support for seek and shorter read to /dev/mdesc
/dev/mdesc on Linux does not support reading arbitrary number
of bytes and seeking while /dev/mdesc on Solaris does. This
causes tools that work on Solaris to break on Linux. This patch
adds these two capabilities to /dev/mdesc.
Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/kernel/mdesc.c | 82 |
1 files changed, 69 insertions, 13 deletions
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index a1a4400d4025..99632a87e697 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c | |||
@@ -906,29 +906,85 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask) | |||
906 | smp_fill_in_sib_core_maps(); | 906 | smp_fill_in_sib_core_maps(); |
907 | } | 907 | } |
908 | 908 | ||
909 | static ssize_t mdesc_read(struct file *file, char __user *buf, | 909 | /* mdesc_open() - Grab a reference to mdesc_handle when /dev/mdesc is |
910 | size_t len, loff_t *offp) | 910 | * opened. Hold this reference until /dev/mdesc is closed to ensure |
911 | * mdesc data structure is not released underneath us. Store the | ||
912 | * pointer to mdesc structure in private_data for read and seek to use | ||
913 | */ | ||
914 | static int mdesc_open(struct inode *inode, struct file *file) | ||
911 | { | 915 | { |
912 | struct mdesc_handle *hp = mdesc_grab(); | 916 | struct mdesc_handle *hp = mdesc_grab(); |
913 | int err; | ||
914 | 917 | ||
915 | if (!hp) | 918 | if (!hp) |
916 | return -ENODEV; | 919 | return -ENODEV; |
917 | 920 | ||
918 | err = hp->handle_size; | 921 | file->private_data = hp; |
919 | if (len < hp->handle_size) | 922 | |
920 | err = -EMSGSIZE; | 923 | return 0; |
921 | else if (copy_to_user(buf, &hp->mdesc, hp->handle_size)) | 924 | } |
922 | err = -EFAULT; | 925 | |
923 | mdesc_release(hp); | 926 | static ssize_t mdesc_read(struct file *file, char __user *buf, |
927 | size_t len, loff_t *offp) | ||
928 | { | ||
929 | struct mdesc_handle *hp = file->private_data; | ||
930 | unsigned char *mdesc; | ||
931 | int bytes_left, count = len; | ||
932 | |||
933 | if (*offp >= hp->handle_size) | ||
934 | return 0; | ||
935 | |||
936 | bytes_left = hp->handle_size - *offp; | ||
937 | if (count > bytes_left) | ||
938 | count = bytes_left; | ||
939 | |||
940 | mdesc = (unsigned char *)&hp->mdesc; | ||
941 | mdesc += *offp; | ||
942 | if (!copy_to_user(buf, mdesc, count)) { | ||
943 | *offp += count; | ||
944 | return count; | ||
945 | } else { | ||
946 | return -EFAULT; | ||
947 | } | ||
948 | } | ||
924 | 949 | ||
925 | return err; | 950 | static loff_t mdesc_llseek(struct file *file, loff_t offset, int whence) |
951 | { | ||
952 | struct mdesc_handle *hp; | ||
953 | |||
954 | switch (whence) { | ||
955 | case SEEK_CUR: | ||
956 | offset += file->f_pos; | ||
957 | break; | ||
958 | case SEEK_SET: | ||
959 | break; | ||
960 | default: | ||
961 | return -EINVAL; | ||
962 | } | ||
963 | |||
964 | hp = file->private_data; | ||
965 | if (offset > hp->handle_size) | ||
966 | return -EINVAL; | ||
967 | else | ||
968 | file->f_pos = offset; | ||
969 | |||
970 | return offset; | ||
971 | } | ||
972 | |||
973 | /* mdesc_close() - /dev/mdesc is being closed, release the reference to | ||
974 | * mdesc structure. | ||
975 | */ | ||
976 | static int mdesc_close(struct inode *inode, struct file *file) | ||
977 | { | ||
978 | mdesc_release(file->private_data); | ||
979 | return 0; | ||
926 | } | 980 | } |
927 | 981 | ||
928 | static const struct file_operations mdesc_fops = { | 982 | static const struct file_operations mdesc_fops = { |
929 | .read = mdesc_read, | 983 | .open = mdesc_open, |
930 | .owner = THIS_MODULE, | 984 | .read = mdesc_read, |
931 | .llseek = noop_llseek, | 985 | .llseek = mdesc_llseek, |
986 | .release = mdesc_close, | ||
987 | .owner = THIS_MODULE, | ||
932 | }; | 988 | }; |
933 | 989 | ||
934 | static struct miscdevice mdesc_misc = { | 990 | static struct miscdevice mdesc_misc = { |