aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r--fs/9p/vfs_inode.c165
1 files changed, 93 insertions, 72 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index e0f20de6aa2b..014c8dd62962 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -23,6 +23,8 @@
23 * 23 *
24 */ 24 */
25 25
26#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27
26#include <linux/module.h> 28#include <linux/module.h>
27#include <linux/errno.h> 29#include <linux/errno.h>
28#include <linux/fs.h> 30#include <linux/fs.h>
@@ -88,6 +90,32 @@ static u32 unixmode2p9mode(struct v9fs_session_info *v9ses, umode_t mode)
88} 90}
89 91
90/** 92/**
93 * p9mode2perm- convert plan9 mode bits to unix permission bits
94 * @v9ses: v9fs session information
95 * @stat: p9_wstat from which mode need to be derived
96 *
97 */
98static int p9mode2perm(struct v9fs_session_info *v9ses,
99 struct p9_wstat *stat)
100{
101 int res;
102 int mode = stat->mode;
103
104 res = mode & S_IALLUGO;
105 if (v9fs_proto_dotu(v9ses)) {
106 if ((mode & P9_DMSETUID) == P9_DMSETUID)
107 res |= S_ISUID;
108
109 if ((mode & P9_DMSETGID) == P9_DMSETGID)
110 res |= S_ISGID;
111
112 if ((mode & P9_DMSETVTX) == P9_DMSETVTX)
113 res |= S_ISVTX;
114 }
115 return res;
116}
117
118/**
91 * p9mode2unixmode- convert plan9 mode bits to unix mode bits 119 * p9mode2unixmode- convert plan9 mode bits to unix mode bits
92 * @v9ses: v9fs session information 120 * @v9ses: v9fs session information
93 * @stat: p9_wstat from which mode need to be derived 121 * @stat: p9_wstat from which mode need to be derived
@@ -100,8 +128,8 @@ static umode_t p9mode2unixmode(struct v9fs_session_info *v9ses,
100 int res; 128 int res;
101 u32 mode = stat->mode; 129 u32 mode = stat->mode;
102 130
103 res = mode & S_IALLUGO;
104 *rdev = 0; 131 *rdev = 0;
132 res = p9mode2perm(v9ses, stat);
105 133
106 if ((mode & P9_DMDIR) == P9_DMDIR) 134 if ((mode & P9_DMDIR) == P9_DMDIR)
107 res |= S_IFDIR; 135 res |= S_IFDIR;
@@ -128,24 +156,13 @@ static umode_t p9mode2unixmode(struct v9fs_session_info *v9ses,
128 res |= S_IFBLK; 156 res |= S_IFBLK;
129 break; 157 break;
130 default: 158 default:
131 P9_DPRINTK(P9_DEBUG_ERROR, 159 p9_debug(P9_DEBUG_ERROR, "Unknown special type %c %s\n",
132 "Unknown special type %c %s\n", type, 160 type, stat->extension);
133 stat->extension);
134 }; 161 };
135 *rdev = MKDEV(major, minor); 162 *rdev = MKDEV(major, minor);
136 } else 163 } else
137 res |= S_IFREG; 164 res |= S_IFREG;
138 165
139 if (v9fs_proto_dotu(v9ses)) {
140 if ((mode & P9_DMSETUID) == P9_DMSETUID)
141 res |= S_ISUID;
142
143 if ((mode & P9_DMSETGID) == P9_DMSETGID)
144 res |= S_ISGID;
145
146 if ((mode & P9_DMSETVTX) == P9_DMSETVTX)
147 res |= S_ISVTX;
148 }
149 return res; 166 return res;
150} 167}
151 168
@@ -275,8 +292,8 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses,
275 } else if (v9fs_proto_dotu(v9ses)) { 292 } else if (v9fs_proto_dotu(v9ses)) {
276 inode->i_op = &v9fs_file_inode_operations; 293 inode->i_op = &v9fs_file_inode_operations;
277 } else { 294 } else {
278 P9_DPRINTK(P9_DEBUG_ERROR, 295 p9_debug(P9_DEBUG_ERROR,
279 "special files without extended mode\n"); 296 "special files without extended mode\n");
280 err = -EINVAL; 297 err = -EINVAL;
281 goto error; 298 goto error;
282 } 299 }
@@ -301,8 +318,8 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses,
301 break; 318 break;
302 case S_IFLNK: 319 case S_IFLNK:
303 if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) { 320 if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) {
304 P9_DPRINTK(P9_DEBUG_ERROR, "extended modes used with " 321 p9_debug(P9_DEBUG_ERROR,
305 "legacy protocol.\n"); 322 "extended modes used with legacy protocol\n");
306 err = -EINVAL; 323 err = -EINVAL;
307 goto error; 324 goto error;
308 } 325 }
@@ -329,8 +346,8 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses,
329 346
330 break; 347 break;
331 default: 348 default:
332 P9_DPRINTK(P9_DEBUG_ERROR, "BAD mode 0x%hx S_IFMT 0x%x\n", 349 p9_debug(P9_DEBUG_ERROR, "BAD mode 0x%hx S_IFMT 0x%x\n",
333 mode, mode & S_IFMT); 350 mode, mode & S_IFMT);
334 err = -EINVAL; 351 err = -EINVAL;
335 goto error; 352 goto error;
336 } 353 }
@@ -352,11 +369,12 @@ struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t rdev)
352 struct inode *inode; 369 struct inode *inode;
353 struct v9fs_session_info *v9ses = sb->s_fs_info; 370 struct v9fs_session_info *v9ses = sb->s_fs_info;
354 371
355 P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %ho\n", sb, mode); 372 p9_debug(P9_DEBUG_VFS, "super block: %p mode: %ho\n", sb, mode);
356 373
357 inode = new_inode(sb); 374 inode = new_inode(sb);
358 if (!inode) { 375 if (!inode) {
359 P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); 376 pr_warn("%s (%d): Problem allocating inode\n",
377 __func__, task_pid_nr(current));
360 return ERR_PTR(-ENOMEM); 378 return ERR_PTR(-ENOMEM);
361 } 379 }
362 err = v9fs_init_inode(v9ses, inode, mode, rdev); 380 err = v9fs_init_inode(v9ses, inode, mode, rdev);
@@ -573,15 +591,15 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
573 struct p9_fid *v9fid, *dfid; 591 struct p9_fid *v9fid, *dfid;
574 struct v9fs_session_info *v9ses; 592 struct v9fs_session_info *v9ses;
575 593
576 P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %x\n", 594 p9_debug(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %x\n",
577 dir, dentry, flags); 595 dir, dentry, flags);
578 596
579 v9ses = v9fs_inode2v9ses(dir); 597 v9ses = v9fs_inode2v9ses(dir);
580 inode = dentry->d_inode; 598 inode = dentry->d_inode;
581 dfid = v9fs_fid_lookup(dentry->d_parent); 599 dfid = v9fs_fid_lookup(dentry->d_parent);
582 if (IS_ERR(dfid)) { 600 if (IS_ERR(dfid)) {
583 retval = PTR_ERR(dfid); 601 retval = PTR_ERR(dfid);
584 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", retval); 602 p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", retval);
585 return retval; 603 return retval;
586 } 604 }
587 if (v9fs_proto_dotl(v9ses)) 605 if (v9fs_proto_dotl(v9ses))
@@ -630,7 +648,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
630 struct p9_fid *dfid, *ofid, *fid; 648 struct p9_fid *dfid, *ofid, *fid;
631 struct inode *inode; 649 struct inode *inode;
632 650
633 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); 651 p9_debug(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
634 652
635 err = 0; 653 err = 0;
636 ofid = NULL; 654 ofid = NULL;
@@ -639,7 +657,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
639 dfid = v9fs_fid_lookup(dentry->d_parent); 657 dfid = v9fs_fid_lookup(dentry->d_parent);
640 if (IS_ERR(dfid)) { 658 if (IS_ERR(dfid)) {
641 err = PTR_ERR(dfid); 659 err = PTR_ERR(dfid);
642 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 660 p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
643 return ERR_PTR(err); 661 return ERR_PTR(err);
644 } 662 }
645 663
@@ -647,36 +665,41 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
647 ofid = p9_client_walk(dfid, 0, NULL, 1); 665 ofid = p9_client_walk(dfid, 0, NULL, 1);
648 if (IS_ERR(ofid)) { 666 if (IS_ERR(ofid)) {
649 err = PTR_ERR(ofid); 667 err = PTR_ERR(ofid);
650 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 668 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
651 return ERR_PTR(err); 669 return ERR_PTR(err);
652 } 670 }
653 671
654 err = p9_client_fcreate(ofid, name, perm, mode, extension); 672 err = p9_client_fcreate(ofid, name, perm, mode, extension);
655 if (err < 0) { 673 if (err < 0) {
656 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err); 674 p9_debug(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err);
657 goto error;
658 }
659
660 /* now walk from the parent so we can get unopened fid */
661 fid = p9_client_walk(dfid, 1, &name, 1);
662 if (IS_ERR(fid)) {
663 err = PTR_ERR(fid);
664 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
665 fid = NULL;
666 goto error; 675 goto error;
667 } 676 }
668 677
669 /* instantiate inode and assign the unopened fid to the dentry */ 678 if (!(perm & P9_DMLINK)) {
670 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 679 /* now walk from the parent so we can get unopened fid */
671 if (IS_ERR(inode)) { 680 fid = p9_client_walk(dfid, 1, &name, 1);
672 err = PTR_ERR(inode); 681 if (IS_ERR(fid)) {
673 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 682 err = PTR_ERR(fid);
674 goto error; 683 p9_debug(P9_DEBUG_VFS,
684 "p9_client_walk failed %d\n", err);
685 fid = NULL;
686 goto error;
687 }
688 /*
689 * instantiate inode and assign the unopened fid to the dentry
690 */
691 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
692 if (IS_ERR(inode)) {
693 err = PTR_ERR(inode);
694 p9_debug(P9_DEBUG_VFS,
695 "inode creation failed %d\n", err);
696 goto error;
697 }
698 err = v9fs_fid_add(dentry, fid);
699 if (err < 0)
700 goto error;
701 d_instantiate(dentry, inode);
675 } 702 }
676 err = v9fs_fid_add(dentry, fid);
677 if (err < 0)
678 goto error;
679 d_instantiate(dentry, inode);
680 return ofid; 703 return ofid;
681error: 704error:
682 if (ofid) 705 if (ofid)
@@ -788,7 +811,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
788 struct p9_fid *fid; 811 struct p9_fid *fid;
789 struct v9fs_session_info *v9ses; 812 struct v9fs_session_info *v9ses;
790 813
791 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); 814 p9_debug(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
792 err = 0; 815 err = 0;
793 v9ses = v9fs_inode2v9ses(dir); 816 v9ses = v9fs_inode2v9ses(dir);
794 perm = unixmode2p9mode(v9ses, mode | S_IFDIR); 817 perm = unixmode2p9mode(v9ses, mode | S_IFDIR);
@@ -826,8 +849,8 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
826 char *name; 849 char *name;
827 int result = 0; 850 int result = 0;
828 851
829 P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", 852 p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n",
830 dir, dentry->d_name.name, dentry, nameidata); 853 dir, dentry->d_name.name, dentry, nameidata);
831 854
832 if (dentry->d_name.len > NAME_MAX) 855 if (dentry->d_name.len > NAME_MAX)
833 return ERR_PTR(-ENAMETOOLONG); 856 return ERR_PTR(-ENAMETOOLONG);
@@ -933,7 +956,7 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
933 struct p9_fid *newdirfid; 956 struct p9_fid *newdirfid;
934 struct p9_wstat wstat; 957 struct p9_wstat wstat;
935 958
936 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 959 p9_debug(P9_DEBUG_VFS, "\n");
937 retval = 0; 960 retval = 0;
938 old_inode = old_dentry->d_inode; 961 old_inode = old_dentry->d_inode;
939 new_inode = new_dentry->d_inode; 962 new_inode = new_dentry->d_inode;
@@ -969,8 +992,7 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
969 * 9P .u can only handle file rename in the same directory 992 * 9P .u can only handle file rename in the same directory
970 */ 993 */
971 994
972 P9_DPRINTK(P9_DEBUG_ERROR, 995 p9_debug(P9_DEBUG_ERROR, "old dir and new dir are different\n");
973 "old dir and new dir are different\n");
974 retval = -EXDEV; 996 retval = -EXDEV;
975 goto clunk_newdir; 997 goto clunk_newdir;
976 } 998 }
@@ -1026,7 +1048,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1026 struct p9_fid *fid; 1048 struct p9_fid *fid;
1027 struct p9_wstat *st; 1049 struct p9_wstat *st;
1028 1050
1029 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); 1051 p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
1030 err = -EPERM; 1052 err = -EPERM;
1031 v9ses = v9fs_dentry2v9ses(dentry); 1053 v9ses = v9fs_dentry2v9ses(dentry);
1032 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 1054 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
@@ -1063,7 +1085,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
1063 struct p9_fid *fid; 1085 struct p9_fid *fid;
1064 struct p9_wstat wstat; 1086 struct p9_wstat wstat;
1065 1087
1066 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 1088 p9_debug(P9_DEBUG_VFS, "\n");
1067 retval = inode_change_ok(dentry->d_inode, iattr); 1089 retval = inode_change_ok(dentry->d_inode, iattr);
1068 if (retval) 1090 if (retval)
1069 return retval; 1091 return retval;
@@ -1162,7 +1184,7 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
1162 set_nlink(inode, i_nlink); 1184 set_nlink(inode, i_nlink);
1163 } 1185 }
1164 } 1186 }
1165 mode = stat->mode & S_IALLUGO; 1187 mode = p9mode2perm(v9ses, stat);
1166 mode |= inode->i_mode & ~S_IALLUGO; 1188 mode |= inode->i_mode & ~S_IALLUGO;
1167 inode->i_mode = mode; 1189 inode->i_mode = mode;
1168 i_size_write(inode, stat->length); 1190 i_size_write(inode, stat->length);
@@ -1208,7 +1230,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
1208 struct p9_fid *fid; 1230 struct p9_fid *fid;
1209 struct p9_wstat *st; 1231 struct p9_wstat *st;
1210 1232
1211 P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); 1233 p9_debug(P9_DEBUG_VFS, " %s\n", dentry->d_name.name);
1212 retval = -EPERM; 1234 retval = -EPERM;
1213 v9ses = v9fs_dentry2v9ses(dentry); 1235 v9ses = v9fs_dentry2v9ses(dentry);
1214 fid = v9fs_fid_lookup(dentry); 1236 fid = v9fs_fid_lookup(dentry);
@@ -1230,8 +1252,8 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
1230 /* copy extension buffer into buffer */ 1252 /* copy extension buffer into buffer */
1231 strncpy(buffer, st->extension, buflen); 1253 strncpy(buffer, st->extension, buflen);
1232 1254
1233 P9_DPRINTK(P9_DEBUG_VFS, 1255 p9_debug(P9_DEBUG_VFS, "%s -> %s (%s)\n",
1234 "%s -> %s (%s)\n", dentry->d_name.name, st->extension, buffer); 1256 dentry->d_name.name, st->extension, buffer);
1235 1257
1236 retval = strnlen(buffer, buflen); 1258 retval = strnlen(buffer, buflen);
1237done: 1259done:
@@ -1252,7 +1274,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
1252 int len = 0; 1274 int len = 0;
1253 char *link = __getname(); 1275 char *link = __getname();
1254 1276
1255 P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name); 1277 p9_debug(P9_DEBUG_VFS, "%s\n", dentry->d_name.name);
1256 1278
1257 if (!link) 1279 if (!link)
1258 link = ERR_PTR(-ENOMEM); 1280 link = ERR_PTR(-ENOMEM);
@@ -1283,8 +1305,8 @@ v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
1283{ 1305{
1284 char *s = nd_get_link(nd); 1306 char *s = nd_get_link(nd);
1285 1307
1286 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, 1308 p9_debug(P9_DEBUG_VFS, " %s %s\n",
1287 IS_ERR(s) ? "<error>" : s); 1309 dentry->d_name.name, IS_ERR(s) ? "<error>" : s);
1288 if (!IS_ERR(s)) 1310 if (!IS_ERR(s))
1289 __putname(s); 1311 __putname(s);
1290} 1312}
@@ -1306,7 +1328,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
1306 1328
1307 v9ses = v9fs_inode2v9ses(dir); 1329 v9ses = v9fs_inode2v9ses(dir);
1308 if (!v9fs_proto_dotu(v9ses)) { 1330 if (!v9fs_proto_dotu(v9ses)) {
1309 P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n"); 1331 p9_debug(P9_DEBUG_ERROR, "not extended\n");
1310 return -EPERM; 1332 return -EPERM;
1311 } 1333 }
1312 1334
@@ -1333,8 +1355,8 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
1333static int 1355static int
1334v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) 1356v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
1335{ 1357{
1336 P9_DPRINTK(P9_DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, 1358 p9_debug(P9_DEBUG_VFS, " %lu,%s,%s\n",
1337 dentry->d_name.name, symname); 1359 dir->i_ino, dentry->d_name.name, symname);
1338 1360
1339 return v9fs_vfs_mkspecial(dir, dentry, P9_DMSYMLINK, symname); 1361 return v9fs_vfs_mkspecial(dir, dentry, P9_DMSYMLINK, symname);
1340} 1362}
@@ -1355,9 +1377,8 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
1355 char *name; 1377 char *name;
1356 struct p9_fid *oldfid; 1378 struct p9_fid *oldfid;
1357 1379
1358 P9_DPRINTK(P9_DEBUG_VFS, 1380 p9_debug(P9_DEBUG_VFS, " %lu,%s,%s\n",
1359 " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, 1381 dir->i_ino, dentry->d_name.name, old_dentry->d_name.name);
1360 old_dentry->d_name.name);
1361 1382
1362 oldfid = v9fs_fid_clone(old_dentry); 1383 oldfid = v9fs_fid_clone(old_dentry);
1363 if (IS_ERR(oldfid)) 1384 if (IS_ERR(oldfid))
@@ -1398,9 +1419,9 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rde
1398 char *name; 1419 char *name;
1399 u32 perm; 1420 u32 perm;
1400 1421
1401 P9_DPRINTK(P9_DEBUG_VFS, 1422 p9_debug(P9_DEBUG_VFS, " %lu,%s mode: %hx MAJOR: %u MINOR: %u\n",
1402 " %lu,%s mode: %hx MAJOR: %u MINOR: %u\n", dir->i_ino, 1423 dir->i_ino, dentry->d_name.name, mode,
1403 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); 1424 MAJOR(rdev), MINOR(rdev));
1404 1425
1405 if (!new_valid_dev(rdev)) 1426 if (!new_valid_dev(rdev))
1406 return -EINVAL; 1427 return -EINVAL;