aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/9p/error.h2
-rw-r--r--fs/9p/vfs_inode.c131
2 files changed, 36 insertions, 97 deletions
diff --git a/fs/9p/error.h b/fs/9p/error.h
index 6dbb66f5b28f..2eb5927d589e 100644
--- a/fs/9p/error.h
+++ b/fs/9p/error.h
@@ -139,7 +139,7 @@ static struct errormap errmap[] = {
139 {"illegal mode", EINVAL}, 139 {"illegal mode", EINVAL},
140 {"illegal name", ENAMETOOLONG}, 140 {"illegal name", ENAMETOOLONG},
141 {"not a directory", ENOTDIR}, 141 {"not a directory", ENOTDIR},
142 {"not a member of proposed group", EINVAL}, 142 {"not a member of proposed group", EPERM},
143 {"not owner", EACCES}, 143 {"not owner", EACCES},
144 {"only owner can change group in wstat", EACCES}, 144 {"only owner can change group in wstat", EACCES},
145 {"read only file system", EROFS}, 145 {"read only file system", EROFS},
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index ef78af7ef04b..6d2357d1dacd 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/fs/9p/vfs_inode.c 2 * linux/fs/9p/vfs_inode.c
3 * 3 *
4 * This file contians vfs inode ops for the 9P2000 protocol. 4 * This file contains vfs inode ops for the 9P2000 protocol.
5 * 5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
@@ -54,7 +54,7 @@ static struct inode_operations v9fs_symlink_inode_operations;
54 * 54 *
55 */ 55 */
56 56
57static inline int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode) 57static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode)
58{ 58{
59 int res; 59 int res;
60 res = mode & 0777; 60 res = mode & 0777;
@@ -92,7 +92,7 @@ static inline int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode)
92 * 92 *
93 */ 93 */
94 94
95static inline int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) 95static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
96{ 96{
97 int res; 97 int res;
98 98
@@ -132,7 +132,7 @@ static inline int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
132 * 132 *
133 */ 133 */
134 134
135static inline void 135static void
136v9fs_blank_mistat(struct v9fs_session_info *v9ses, struct v9fs_stat *mistat) 136v9fs_blank_mistat(struct v9fs_session_info *v9ses, struct v9fs_stat *mistat)
137{ 137{
138 mistat->type = ~0; 138 mistat->type = ~0;
@@ -160,7 +160,7 @@ v9fs_blank_mistat(struct v9fs_session_info *v9ses, struct v9fs_stat *mistat)
160/** 160/**
161 * v9fs_mistat2unix - convert mistat to unix stat 161 * v9fs_mistat2unix - convert mistat to unix stat
162 * @mistat: Plan 9 metadata (mistat) structure 162 * @mistat: Plan 9 metadata (mistat) structure
163 * @stat: unix metadata (stat) structure to populate 163 * @buf: unix metadata (stat) structure to populate
164 * @sb: superblock 164 * @sb: superblock
165 * 165 *
166 */ 166 */
@@ -177,22 +177,11 @@ v9fs_mistat2unix(struct v9fs_stat *mistat, struct stat *buf,
177 buf->st_mtime = mistat->mtime; 177 buf->st_mtime = mistat->mtime;
178 buf->st_ctime = mistat->mtime; 178 buf->st_ctime = mistat->mtime;
179 179
180 if (v9ses && v9ses->extended) {
181 /* TODO: string to uid mapping via user-space daemon */
182 buf->st_uid = mistat->n_uid;
183 buf->st_gid = mistat->n_gid;
184
185 sscanf(mistat->uid, "%x", (unsigned int *)&buf->st_uid);
186 sscanf(mistat->gid, "%x", (unsigned int *)&buf->st_gid);
187 } else {
188 buf->st_uid = v9ses->uid;
189 buf->st_gid = v9ses->gid;
190 }
191
192 buf->st_uid = (unsigned short)-1; 180 buf->st_uid = (unsigned short)-1;
193 buf->st_gid = (unsigned short)-1; 181 buf->st_gid = (unsigned short)-1;
194 182
195 if (v9ses && v9ses->extended) { 183 if (v9ses && v9ses->extended) {
184 /* TODO: string to uid mapping via user-space daemon */
196 if (mistat->n_uid != -1) 185 if (mistat->n_uid != -1)
197 sscanf(mistat->uid, "%x", (unsigned int *)&buf->st_uid); 186 sscanf(mistat->uid, "%x", (unsigned int *)&buf->st_uid);
198 187
@@ -290,7 +279,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
290 * @dir: directory inode file is being created in 279 * @dir: directory inode file is being created in
291 * @file_dentry: dentry file is being created in 280 * @file_dentry: dentry file is being created in
292 * @perm: permissions file is being created with 281 * @perm: permissions file is being created with
293 * @open_mode: resulting open mode for file ??? 282 * @open_mode: resulting open mode for file
294 * 283 *
295 */ 284 */
296 285
@@ -434,9 +423,9 @@ v9fs_create(struct inode *dir,
434 423
435/** 424/**
436 * v9fs_remove - helper function to remove files and directories 425 * v9fs_remove - helper function to remove files and directories
437 * @inode: directory inode that is being deleted 426 * @dir: directory inode that is being deleted
438 * @dentry: dentry that is being deleted 427 * @file: dentry that is being deleted
439 * @rmdir: where we are a file or a directory 428 * @rmdir: removing a directory
440 * 429 *
441 */ 430 */
442 431
@@ -502,7 +491,7 @@ v9fs_vfs_create(struct inode *inode, struct dentry *dentry, int perm,
502 491
503/** 492/**
504 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory 493 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
505 * @i: inode that is being unlinked 494 * @inode: inode that is being unlinked
506 * @dentry: dentry that is being unlinked 495 * @dentry: dentry that is being unlinked
507 * @mode: mode for new directory 496 * @mode: mode for new directory
508 * 497 *
@@ -624,7 +613,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
624/** 613/**
625 * v9fs_vfs_unlink - VFS unlink hook to delete an inode 614 * v9fs_vfs_unlink - VFS unlink hook to delete an inode
626 * @i: inode that is being unlinked 615 * @i: inode that is being unlinked
627 * @dentry: dentry that is being unlinked 616 * @d: dentry that is being unlinked
628 * 617 *
629 */ 618 */
630 619
@@ -636,7 +625,7 @@ static int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
636/** 625/**
637 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory 626 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
638 * @i: inode that is being unlinked 627 * @i: inode that is being unlinked
639 * @dentry: dentry that is being unlinked 628 * @d: dentry that is being unlinked
640 * 629 *
641 */ 630 */
642 631
@@ -674,6 +663,9 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
674 663
675 dprintk(DEBUG_VFS, "\n"); 664 dprintk(DEBUG_VFS, "\n");
676 665
666 if (!mistat)
667 return -ENOMEM;
668
677 if ((!oldfid) || (!olddirfid) || (!newdirfid)) { 669 if ((!oldfid) || (!olddirfid) || (!newdirfid)) {
678 dprintk(DEBUG_ERROR, "problem with arguments\n"); 670 dprintk(DEBUG_ERROR, "problem with arguments\n");
679 return -EBADF; 671 return -EBADF;
@@ -771,20 +763,21 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
771{ 763{
772 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 764 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
773 struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP); 765 struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
774 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
775 struct v9fs_fcall *fcall = NULL; 766 struct v9fs_fcall *fcall = NULL;
767 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
776 int res = -EPERM; 768 int res = -EPERM;
777 769
778 dprintk(DEBUG_VFS, "\n"); 770 dprintk(DEBUG_VFS, "\n");
771
772 if (!mistat)
773 return -ENOMEM;
774
779 if (!fid) { 775 if (!fid) {
780 dprintk(DEBUG_ERROR, 776 dprintk(DEBUG_ERROR,
781 "Couldn't find fid associated with dentry\n"); 777 "Couldn't find fid associated with dentry\n");
782 return -EBADF; 778 return -EBADF;
783 } 779 }
784 780
785 if (!mistat)
786 return -ENOMEM;
787
788 v9fs_blank_mistat(v9ses, mistat); 781 v9fs_blank_mistat(v9ses, mistat);
789 if (iattr->ia_valid & ATTR_MODE) 782 if (iattr->ia_valid & ATTR_MODE)
790 mistat->mode = unixmode2p9mode(v9ses, iattr->ia_mode); 783 mistat->mode = unixmode2p9mode(v9ses, iattr->ia_mode);
@@ -799,72 +792,19 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
799 mistat->length = iattr->ia_size; 792 mistat->length = iattr->ia_size;
800 793
801 if (v9ses->extended) { 794 if (v9ses->extended) {
802 char *uid = kmalloc(strlen(mistat->uid), GFP_KERNEL); 795 char *ptr = mistat->data+1;
803 char *gid = kmalloc(strlen(mistat->gid), GFP_KERNEL);
804 char *muid = kmalloc(strlen(mistat->muid), GFP_KERNEL);
805 char *name = kmalloc(strlen(mistat->name), GFP_KERNEL);
806 char *extension = kmalloc(strlen(mistat->extension),
807 GFP_KERNEL);
808
809 if ((!uid) || (!gid) || (!muid) || (!name) || (!extension)) {
810 kfree(uid);
811 kfree(gid);
812 kfree(muid);
813 kfree(name);
814 kfree(extension);
815
816 return -ENOMEM;
817 }
818
819 strcpy(uid, mistat->uid);
820 strcpy(gid, mistat->gid);
821 strcpy(muid, mistat->muid);
822 strcpy(name, mistat->name);
823 strcpy(extension, mistat->extension);
824 796
825 if (iattr->ia_valid & ATTR_UID) { 797 if (iattr->ia_valid & ATTR_UID) {
826 if (strlen(uid) != 8) { 798 mistat->uid = ptr;
827 dprintk(DEBUG_ERROR, "uid strlen is %u not 8\n", 799 ptr += 1+sprintf(ptr, "%08x", iattr->ia_uid);
828 (unsigned int)strlen(uid));
829 sprintf(uid, "%08x", iattr->ia_uid);
830 } else {
831 kfree(uid);
832 uid = kmalloc(9, GFP_KERNEL);
833 }
834
835 sprintf(uid, "%08x", iattr->ia_uid);
836 mistat->n_uid = iattr->ia_uid; 800 mistat->n_uid = iattr->ia_uid;
837 } 801 }
838 802
839 if (iattr->ia_valid & ATTR_GID) { 803 if (iattr->ia_valid & ATTR_GID) {
840 if (strlen(gid) != 8) 804 mistat->gid = ptr;
841 dprintk(DEBUG_ERROR, "gid strlen is %u not 8\n", 805 ptr += 1+sprintf(ptr, "%08x", iattr->ia_gid);
842 (unsigned int)strlen(gid));
843 else {
844 kfree(gid);
845 gid = kmalloc(9, GFP_KERNEL);
846 }
847
848 sprintf(gid, "%08x", iattr->ia_gid);
849 mistat->n_gid = iattr->ia_gid; 806 mistat->n_gid = iattr->ia_gid;
850 } 807 }
851
852 mistat->uid = mistat->data;
853 strcpy(mistat->uid, uid);
854 mistat->gid = mistat->data + strlen(uid) + 1;
855 strcpy(mistat->gid, gid);
856 mistat->muid = mistat->gid + strlen(gid) + 1;
857 strcpy(mistat->muid, muid);
858 mistat->name = mistat->muid + strlen(muid) + 1;
859 strcpy(mistat->name, name);
860 mistat->extension = mistat->name + strlen(name) + 1;
861 strcpy(mistat->extension, extension);
862
863 kfree(uid);
864 kfree(gid);
865 kfree(muid);
866 kfree(name);
867 kfree(extension);
868 } 808 }
869 809
870 res = v9fs_t_wstat(v9ses, fid->fid, mistat, &fcall); 810 res = v9fs_t_wstat(v9ses, fid->fid, mistat, &fcall);
@@ -985,17 +925,14 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
985 int retval = -EPERM; 925 int retval = -EPERM;
986 struct v9fs_fid *newfid; 926 struct v9fs_fid *newfid;
987 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); 927 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
988 struct super_block *sb = dir ? dir->i_sb : NULL;
989 struct v9fs_fcall *fcall = NULL; 928 struct v9fs_fcall *fcall = NULL;
990 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); 929 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
991 930
992 dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, 931 dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
993 symname); 932 symname);
994 933
995 if ((!dentry) || (!sb) || (!v9ses)) { 934 if (!mistat)
996 dprintk(DEBUG_ERROR, "problem with arguments\n"); 935 return -ENOMEM;
997 return -EBADF;
998 }
999 936
1000 if (!v9ses->extended) { 937 if (!v9ses->extended) {
1001 dprintk(DEBUG_ERROR, "not extended\n"); 938 dprintk(DEBUG_ERROR, "not extended\n");
@@ -1040,7 +977,7 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
1040/** 977/**
1041 * v9fs_readlink - read a symlink's location (internal version) 978 * v9fs_readlink - read a symlink's location (internal version)
1042 * @dentry: dentry for symlink 979 * @dentry: dentry for symlink
1043 * @buf: buffer to load symlink location into 980 * @buffer: buffer to load symlink location into
1044 * @buflen: length of buffer 981 * @buflen: length of buffer
1045 * 982 *
1046 */ 983 */
@@ -1179,7 +1116,7 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void
1179 * v9fs_vfs_link - create a hardlink 1116 * v9fs_vfs_link - create a hardlink
1180 * @old_dentry: dentry for file to link to 1117 * @old_dentry: dentry for file to link to
1181 * @dir: inode destination for new link 1118 * @dir: inode destination for new link
1182 * @new_dentry: dentry for link 1119 * @dentry: dentry for link
1183 * 1120 *
1184 */ 1121 */
1185 1122
@@ -1274,6 +1211,9 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
1274 dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, 1211 dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
1275 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); 1212 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
1276 1213
1214 if (!mistat)
1215 return -ENOMEM;
1216
1277 if (!new_valid_dev(rdev)) { 1217 if (!new_valid_dev(rdev)) {
1278 retval = -EINVAL; 1218 retval = -EINVAL;
1279 goto FreeMem; 1219 goto FreeMem;
@@ -1302,7 +1242,8 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
1302 sprintf(symname, "b %u %u", MAJOR(rdev), MINOR(rdev)); 1242 sprintf(symname, "b %u %u", MAJOR(rdev), MINOR(rdev));
1303 else if (S_ISCHR(mode)) 1243 else if (S_ISCHR(mode))
1304 sprintf(symname, "c %u %u", MAJOR(rdev), MINOR(rdev)); 1244 sprintf(symname, "c %u %u", MAJOR(rdev), MINOR(rdev));
1305 else if (S_ISFIFO(mode)) ; /* DO NOTHING */ 1245 else if (S_ISFIFO(mode))
1246 ; /* DO NOTHING */
1306 else { 1247 else {
1307 retval = -EINVAL; 1248 retval = -EINVAL;
1308 goto FreeMem; 1249 goto FreeMem;
@@ -1319,8 +1260,6 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
1319 FCALL_ERROR(fcall)); 1260 FCALL_ERROR(fcall));
1320 goto FreeMem; 1261 goto FreeMem;
1321 } 1262 }
1322
1323 kfree(fcall);
1324 } 1263 }
1325 1264
1326 /* need to update dcache so we show up */ 1265 /* need to update dcache so we show up */