aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p')
-rw-r--r--fs/9p/acl.c37
-rw-r--r--fs/9p/acl.h20
-rw-r--r--fs/9p/vfs_dentry.c1
-rw-r--r--fs/9p/vfs_file.c10
-rw-r--r--fs/9p/vfs_inode_dotl.c75
-rw-r--r--fs/9p/vfs_super.c2
-rw-r--r--fs/9p/xattr.c33
-rw-r--r--fs/9p/xattr.h2
8 files changed, 97 insertions, 83 deletions
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index 15b679166201..7af425f53bee 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -23,6 +23,7 @@
23#include "acl.h" 23#include "acl.h"
24#include "v9fs.h" 24#include "v9fs.h"
25#include "v9fs_vfs.h" 25#include "v9fs_vfs.h"
26#include "fid.h"
26 27
27static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name) 28static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name)
28{ 29{
@@ -113,16 +114,12 @@ struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type)
113 114
114} 115}
115 116
116static int v9fs_set_acl(struct dentry *dentry, int type, struct posix_acl *acl) 117static int v9fs_set_acl(struct p9_fid *fid, int type, struct posix_acl *acl)
117{ 118{
118 int retval; 119 int retval;
119 char *name; 120 char *name;
120 size_t size; 121 size_t size;
121 void *buffer; 122 void *buffer;
122 struct inode *inode = dentry->d_inode;
123
124 set_cached_acl(inode, type, acl);
125
126 if (!acl) 123 if (!acl)
127 return 0; 124 return 0;
128 125
@@ -144,17 +141,16 @@ static int v9fs_set_acl(struct dentry *dentry, int type, struct posix_acl *acl)
144 default: 141 default:
145 BUG(); 142 BUG();
146 } 143 }
147 retval = v9fs_xattr_set(dentry, name, buffer, size, 0); 144 retval = v9fs_fid_xattr_set(fid, name, buffer, size, 0);
148err_free_out: 145err_free_out:
149 kfree(buffer); 146 kfree(buffer);
150 return retval; 147 return retval;
151} 148}
152 149
153int v9fs_acl_chmod(struct dentry *dentry) 150int v9fs_acl_chmod(struct inode *inode, struct p9_fid *fid)
154{ 151{
155 int retval = 0; 152 int retval = 0;
156 struct posix_acl *acl; 153 struct posix_acl *acl;
157 struct inode *inode = dentry->d_inode;
158 154
159 if (S_ISLNK(inode->i_mode)) 155 if (S_ISLNK(inode->i_mode))
160 return -EOPNOTSUPP; 156 return -EOPNOTSUPP;
@@ -163,25 +159,30 @@ int v9fs_acl_chmod(struct dentry *dentry)
163 retval = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); 159 retval = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
164 if (retval) 160 if (retval)
165 return retval; 161 return retval;
166 retval = v9fs_set_acl(dentry, ACL_TYPE_ACCESS, acl); 162 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
163 retval = v9fs_set_acl(fid, ACL_TYPE_ACCESS, acl);
167 posix_acl_release(acl); 164 posix_acl_release(acl);
168 } 165 }
169 return retval; 166 return retval;
170} 167}
171 168
172int v9fs_set_create_acl(struct dentry *dentry, 169int v9fs_set_create_acl(struct inode *inode, struct p9_fid *fid,
173 struct posix_acl **dpacl, struct posix_acl **pacl) 170 struct posix_acl *dacl, struct posix_acl *acl)
174{ 171{
175 if (dentry) { 172 set_cached_acl(inode, ACL_TYPE_DEFAULT, dacl);
176 v9fs_set_acl(dentry, ACL_TYPE_DEFAULT, *dpacl); 173 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
177 v9fs_set_acl(dentry, ACL_TYPE_ACCESS, *pacl); 174 v9fs_set_acl(fid, ACL_TYPE_DEFAULT, dacl);
178 } 175 v9fs_set_acl(fid, ACL_TYPE_ACCESS, acl);
179 posix_acl_release(*dpacl);
180 posix_acl_release(*pacl);
181 *dpacl = *pacl = NULL;
182 return 0; 176 return 0;
183} 177}
184 178
179void v9fs_put_acl(struct posix_acl *dacl,
180 struct posix_acl *acl)
181{
182 posix_acl_release(dacl);
183 posix_acl_release(acl);
184}
185
185int v9fs_acl_mode(struct inode *dir, umode_t *modep, 186int v9fs_acl_mode(struct inode *dir, umode_t *modep,
186 struct posix_acl **dpacl, struct posix_acl **pacl) 187 struct posix_acl **dpacl, struct posix_acl **pacl)
187{ 188{
diff --git a/fs/9p/acl.h b/fs/9p/acl.h
index 559556411965..e4f7e882272b 100644
--- a/fs/9p/acl.h
+++ b/fs/9p/acl.h
@@ -17,27 +17,33 @@
17#ifdef CONFIG_9P_FS_POSIX_ACL 17#ifdef CONFIG_9P_FS_POSIX_ACL
18extern int v9fs_get_acl(struct inode *, struct p9_fid *); 18extern int v9fs_get_acl(struct inode *, struct p9_fid *);
19extern struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type); 19extern struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type);
20extern int v9fs_acl_chmod(struct dentry *); 20extern int v9fs_acl_chmod(struct inode *, struct p9_fid *);
21extern int v9fs_set_create_acl(struct dentry *, 21extern int v9fs_set_create_acl(struct inode *, struct p9_fid *,
22 struct posix_acl **, struct posix_acl **); 22 struct posix_acl *, struct posix_acl *);
23extern int v9fs_acl_mode(struct inode *dir, umode_t *modep, 23extern int v9fs_acl_mode(struct inode *dir, umode_t *modep,
24 struct posix_acl **dpacl, struct posix_acl **pacl); 24 struct posix_acl **dpacl, struct posix_acl **pacl);
25extern void v9fs_put_acl(struct posix_acl *dacl, struct posix_acl *acl);
25#else 26#else
26#define v9fs_iop_get_acl NULL 27#define v9fs_iop_get_acl NULL
27static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid) 28static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
28{ 29{
29 return 0; 30 return 0;
30} 31}
31static inline int v9fs_acl_chmod(struct dentry *dentry) 32static inline int v9fs_acl_chmod(struct inode *inode, struct p9_fid *fid)
32{ 33{
33 return 0; 34 return 0;
34} 35}
35static inline int v9fs_set_create_acl(struct dentry *dentry, 36static inline int v9fs_set_create_acl(struct inode *inode,
36 struct posix_acl **dpacl, 37 struct p9_fid *fid,
37 struct posix_acl **pacl) 38 struct posix_acl *dacl,
39 struct posix_acl *acl)
38{ 40{
39 return 0; 41 return 0;
40} 42}
43static inline void v9fs_put_acl(struct posix_acl *dacl,
44 struct posix_acl *acl)
45{
46}
41static inline int v9fs_acl_mode(struct inode *dir, umode_t *modep, 47static inline int v9fs_acl_mode(struct inode *dir, umode_t *modep,
42 struct posix_acl **dpacl, 48 struct posix_acl **dpacl,
43 struct posix_acl **pacl) 49 struct posix_acl **pacl)
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index 64600b5d0522..9ad68628522c 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -137,6 +137,7 @@ out_valid:
137 137
138const struct dentry_operations v9fs_cached_dentry_operations = { 138const struct dentry_operations v9fs_cached_dentry_operations = {
139 .d_revalidate = v9fs_lookup_revalidate, 139 .d_revalidate = v9fs_lookup_revalidate,
140 .d_weak_revalidate = v9fs_lookup_revalidate,
140 .d_delete = v9fs_cached_dentry_delete, 141 .d_delete = v9fs_cached_dentry_delete,
141 .d_release = v9fs_dentry_release, 142 .d_release = v9fs_dentry_release,
142}; 143};
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index c921ac92ea4c..d384a8b77ee8 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -129,7 +129,7 @@ out_error:
129static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) 129static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
130{ 130{
131 int res = 0; 131 int res = 0;
132 struct inode *inode = filp->f_path.dentry->d_inode; 132 struct inode *inode = file_inode(filp);
133 133
134 p9_debug(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); 134 p9_debug(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
135 135
@@ -298,7 +298,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
298 298
299static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl) 299static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl)
300{ 300{
301 struct inode *inode = filp->f_path.dentry->d_inode; 301 struct inode *inode = file_inode(filp);
302 int ret = -ENOLCK; 302 int ret = -ENOLCK;
303 303
304 p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n", 304 p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n",
@@ -334,7 +334,7 @@ out_err:
334static int v9fs_file_flock_dotl(struct file *filp, int cmd, 334static int v9fs_file_flock_dotl(struct file *filp, int cmd,
335 struct file_lock *fl) 335 struct file_lock *fl)
336{ 336{
337 struct inode *inode = filp->f_path.dentry->d_inode; 337 struct inode *inode = file_inode(filp);
338 int ret = -ENOLCK; 338 int ret = -ENOLCK;
339 339
340 p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n", 340 p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n",
@@ -525,7 +525,7 @@ v9fs_file_write(struct file *filp, const char __user * data,
525 if (!count) 525 if (!count)
526 goto out; 526 goto out;
527 527
528 retval = v9fs_file_write_internal(filp->f_path.dentry->d_inode, 528 retval = v9fs_file_write_internal(file_inode(filp),
529 filp->private_data, 529 filp->private_data,
530 data, count, &origin, 1); 530 data, count, &origin, 1);
531 /* update offset on successful write */ 531 /* update offset on successful write */
@@ -600,7 +600,7 @@ v9fs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
600 struct v9fs_inode *v9inode; 600 struct v9fs_inode *v9inode;
601 struct page *page = vmf->page; 601 struct page *page = vmf->page;
602 struct file *filp = vma->vm_file; 602 struct file *filp = vma->vm_file;
603 struct inode *inode = filp->f_path.dentry->d_inode; 603 struct inode *inode = file_inode(filp);
604 604
605 605
606 p9_debug(P9_DEBUG_VFS, "page %p fid %lx\n", 606 p9_debug(P9_DEBUG_VFS, "page %p fid %lx\n",
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 07f409288d1b..61e4fa70a6fa 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -330,14 +330,14 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
330 p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err); 330 p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
331 goto error; 331 goto error;
332 } 332 }
333 /* Now set the ACL based on the default value */
334 v9fs_set_create_acl(inode, fid, dacl, pacl);
335
333 err = v9fs_fid_add(dentry, fid); 336 err = v9fs_fid_add(dentry, fid);
334 if (err < 0) 337 if (err < 0)
335 goto error; 338 goto error;
336 d_instantiate(dentry, inode); 339 d_instantiate(dentry, inode);
337 340
338 /* Now set the ACL based on the default value */
339 v9fs_set_create_acl(dentry, &dacl, &pacl);
340
341 v9inode = V9FS_I(inode); 341 v9inode = V9FS_I(inode);
342 mutex_lock(&v9inode->v_mutex); 342 mutex_lock(&v9inode->v_mutex);
343 if (v9ses->cache && !v9inode->writeback_fid && 343 if (v9ses->cache && !v9inode->writeback_fid &&
@@ -369,6 +369,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
369#endif 369#endif
370 *opened |= FILE_CREATED; 370 *opened |= FILE_CREATED;
371out: 371out:
372 v9fs_put_acl(dacl, pacl);
372 dput(res); 373 dput(res);
373 return err; 374 return err;
374 375
@@ -378,7 +379,6 @@ error:
378err_clunk_old_fid: 379err_clunk_old_fid:
379 if (ofid) 380 if (ofid)
380 p9_client_clunk(ofid); 381 p9_client_clunk(ofid);
381 v9fs_set_create_acl(NULL, &dacl, &pacl);
382 goto out; 382 goto out;
383} 383}
384 384
@@ -435,17 +435,17 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
435 if (err < 0) 435 if (err < 0)
436 goto error; 436 goto error;
437 437
438 fid = p9_client_walk(dfid, 1, &name, 1);
439 if (IS_ERR(fid)) {
440 err = PTR_ERR(fid);
441 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
442 err);
443 fid = NULL;
444 goto error;
445 }
446
438 /* instantiate inode and assign the unopened fid to the dentry */ 447 /* instantiate inode and assign the unopened fid to the dentry */
439 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 448 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
440 fid = p9_client_walk(dfid, 1, &name, 1);
441 if (IS_ERR(fid)) {
442 err = PTR_ERR(fid);
443 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
444 err);
445 fid = NULL;
446 goto error;
447 }
448
449 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 449 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
450 if (IS_ERR(inode)) { 450 if (IS_ERR(inode)) {
451 err = PTR_ERR(inode); 451 err = PTR_ERR(inode);
@@ -456,6 +456,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
456 err = v9fs_fid_add(dentry, fid); 456 err = v9fs_fid_add(dentry, fid);
457 if (err < 0) 457 if (err < 0)
458 goto error; 458 goto error;
459 v9fs_set_create_acl(inode, fid, dacl, pacl);
459 d_instantiate(dentry, inode); 460 d_instantiate(dentry, inode);
460 fid = NULL; 461 fid = NULL;
461 } else { 462 } else {
@@ -469,16 +470,15 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
469 err = PTR_ERR(inode); 470 err = PTR_ERR(inode);
470 goto error; 471 goto error;
471 } 472 }
473 v9fs_set_create_acl(inode, fid, dacl, pacl);
472 d_instantiate(dentry, inode); 474 d_instantiate(dentry, inode);
473 } 475 }
474 /* Now set the ACL based on the default value */
475 v9fs_set_create_acl(dentry, &dacl, &pacl);
476 inc_nlink(dir); 476 inc_nlink(dir);
477 v9fs_invalidate_inode_attr(dir); 477 v9fs_invalidate_inode_attr(dir);
478error: 478error:
479 if (fid) 479 if (fid)
480 p9_client_clunk(fid); 480 p9_client_clunk(fid);
481 v9fs_set_create_acl(NULL, &dacl, &pacl); 481 v9fs_put_acl(dacl, pacl);
482 return err; 482 return err;
483} 483}
484 484
@@ -572,10 +572,11 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
572 struct v9fs_session_info *v9ses; 572 struct v9fs_session_info *v9ses;
573 struct p9_fid *fid; 573 struct p9_fid *fid;
574 struct p9_iattr_dotl p9attr; 574 struct p9_iattr_dotl p9attr;
575 struct inode *inode = dentry->d_inode;
575 576
576 p9_debug(P9_DEBUG_VFS, "\n"); 577 p9_debug(P9_DEBUG_VFS, "\n");
577 578
578 retval = inode_change_ok(dentry->d_inode, iattr); 579 retval = inode_change_ok(inode, iattr);
579 if (retval) 580 if (retval)
580 return retval; 581 return retval;
581 582
@@ -596,23 +597,23 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
596 return PTR_ERR(fid); 597 return PTR_ERR(fid);
597 598
598 /* Write all dirty data */ 599 /* Write all dirty data */
599 if (S_ISREG(dentry->d_inode->i_mode)) 600 if (S_ISREG(inode->i_mode))
600 filemap_write_and_wait(dentry->d_inode->i_mapping); 601 filemap_write_and_wait(inode->i_mapping);
601 602
602 retval = p9_client_setattr(fid, &p9attr); 603 retval = p9_client_setattr(fid, &p9attr);
603 if (retval < 0) 604 if (retval < 0)
604 return retval; 605 return retval;
605 606
606 if ((iattr->ia_valid & ATTR_SIZE) && 607 if ((iattr->ia_valid & ATTR_SIZE) &&
607 iattr->ia_size != i_size_read(dentry->d_inode)) 608 iattr->ia_size != i_size_read(inode))
608 truncate_setsize(dentry->d_inode, iattr->ia_size); 609 truncate_setsize(inode, iattr->ia_size);
609 610
610 v9fs_invalidate_inode_attr(dentry->d_inode); 611 v9fs_invalidate_inode_attr(inode);
611 setattr_copy(dentry->d_inode, iattr); 612 setattr_copy(inode, iattr);
612 mark_inode_dirty(dentry->d_inode); 613 mark_inode_dirty(inode);
613 if (iattr->ia_valid & ATTR_MODE) { 614 if (iattr->ia_valid & ATTR_MODE) {
614 /* We also want to update ACL when we update mode bits */ 615 /* We also want to update ACL when we update mode bits */
615 retval = v9fs_acl_chmod(dentry); 616 retval = v9fs_acl_chmod(inode, fid);
616 if (retval < 0) 617 if (retval < 0)
617 return retval; 618 return retval;
618 } 619 }
@@ -880,17 +881,17 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
880 goto error; 881 goto error;
881 882
882 v9fs_invalidate_inode_attr(dir); 883 v9fs_invalidate_inode_attr(dir);
884 fid = p9_client_walk(dfid, 1, &name, 1);
885 if (IS_ERR(fid)) {
886 err = PTR_ERR(fid);
887 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
888 err);
889 fid = NULL;
890 goto error;
891 }
892
883 /* instantiate inode and assign the unopened fid to the dentry */ 893 /* instantiate inode and assign the unopened fid to the dentry */
884 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 894 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
885 fid = p9_client_walk(dfid, 1, &name, 1);
886 if (IS_ERR(fid)) {
887 err = PTR_ERR(fid);
888 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
889 err);
890 fid = NULL;
891 goto error;
892 }
893
894 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 895 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
895 if (IS_ERR(inode)) { 896 if (IS_ERR(inode)) {
896 err = PTR_ERR(inode); 897 err = PTR_ERR(inode);
@@ -898,6 +899,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
898 err); 899 err);
899 goto error; 900 goto error;
900 } 901 }
902 v9fs_set_create_acl(inode, fid, dacl, pacl);
901 err = v9fs_fid_add(dentry, fid); 903 err = v9fs_fid_add(dentry, fid);
902 if (err < 0) 904 if (err < 0)
903 goto error; 905 goto error;
@@ -913,14 +915,13 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
913 err = PTR_ERR(inode); 915 err = PTR_ERR(inode);
914 goto error; 916 goto error;
915 } 917 }
918 v9fs_set_create_acl(inode, fid, dacl, pacl);
916 d_instantiate(dentry, inode); 919 d_instantiate(dentry, inode);
917 } 920 }
918 /* Now set the ACL based on the default value */
919 v9fs_set_create_acl(dentry, &dacl, &pacl);
920error: 921error:
921 if (fid) 922 if (fid)
922 p9_client_clunk(fid); 923 p9_client_clunk(fid);
923 v9fs_set_create_acl(NULL, &dacl, &pacl); 924 v9fs_put_acl(dacl, pacl);
924 return err; 925 return err;
925} 926}
926 927
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 137d50396898..91dad63e5a2d 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -363,5 +363,5 @@ struct file_system_type v9fs_fs_type = {
363 .mount = v9fs_mount, 363 .mount = v9fs_mount,
364 .kill_sb = v9fs_kill_super, 364 .kill_sb = v9fs_kill_super,
365 .owner = THIS_MODULE, 365 .owner = THIS_MODULE,
366 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT, 366 .fs_flags = FS_RENAME_DOES_D_MOVE,
367}; 367};
diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c
index 29653b70a9c3..c45e016b190f 100644
--- a/fs/9p/xattr.c
+++ b/fs/9p/xattr.c
@@ -111,19 +111,26 @@ ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
111int v9fs_xattr_set(struct dentry *dentry, const char *name, 111int v9fs_xattr_set(struct dentry *dentry, const char *name,
112 const void *value, size_t value_len, int flags) 112 const void *value, size_t value_len, int flags)
113{ 113{
114 struct p9_fid *fid = v9fs_fid_lookup(dentry);
115 if (IS_ERR(fid))
116 return PTR_ERR(fid);
117 return v9fs_fid_xattr_set(fid, name, value, value_len, flags);
118}
119
120int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
121 const void *value, size_t value_len, int flags)
122{
114 u64 offset = 0; 123 u64 offset = 0;
115 int retval, msize, write_count; 124 int retval, msize, write_count;
116 struct p9_fid *fid = NULL;
117 125
118 p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu flags = %d\n", 126 p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu flags = %d\n",
119 name, value_len, flags); 127 name, value_len, flags);
120 128
121 fid = v9fs_fid_clone(dentry); 129 /* Clone it */
122 if (IS_ERR(fid)) { 130 fid = p9_client_walk(fid, 0, NULL, 1);
123 retval = PTR_ERR(fid); 131 if (IS_ERR(fid))
124 fid = NULL; 132 return PTR_ERR(fid);
125 goto error; 133
126 }
127 /* 134 /*
128 * On success fid points to xattr 135 * On success fid points to xattr
129 */ 136 */
@@ -131,7 +138,8 @@ int v9fs_xattr_set(struct dentry *dentry, const char *name,
131 if (retval < 0) { 138 if (retval < 0) {
132 p9_debug(P9_DEBUG_VFS, "p9_client_xattrcreate failed %d\n", 139 p9_debug(P9_DEBUG_VFS, "p9_client_xattrcreate failed %d\n",
133 retval); 140 retval);
134 goto error; 141 p9_client_clunk(fid);
142 return retval;
135 } 143 }
136 msize = fid->clnt->msize; 144 msize = fid->clnt->msize;
137 while (value_len) { 145 while (value_len) {
@@ -144,17 +152,12 @@ int v9fs_xattr_set(struct dentry *dentry, const char *name,
144 if (write_count < 0) { 152 if (write_count < 0) {
145 /* error in xattr write */ 153 /* error in xattr write */
146 retval = write_count; 154 retval = write_count;
147 goto error; 155 break;
148 } 156 }
149 offset += write_count; 157 offset += write_count;
150 value_len -= write_count; 158 value_len -= write_count;
151 } 159 }
152 /* Total read xattr bytes */ 160 return p9_client_clunk(fid);
153 retval = offset;
154error:
155 if (fid)
156 retval = p9_client_clunk(fid);
157 return retval;
158} 161}
159 162
160ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) 163ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
diff --git a/fs/9p/xattr.h b/fs/9p/xattr.h
index eaa837c53bd5..eec348a3df71 100644
--- a/fs/9p/xattr.h
+++ b/fs/9p/xattr.h
@@ -27,6 +27,8 @@ extern ssize_t v9fs_fid_xattr_get(struct p9_fid *, const char *,
27 void *, size_t); 27 void *, size_t);
28extern ssize_t v9fs_xattr_get(struct dentry *, const char *, 28extern ssize_t v9fs_xattr_get(struct dentry *, const char *,
29 void *, size_t); 29 void *, size_t);
30extern int v9fs_fid_xattr_set(struct p9_fid *, const char *,
31 const void *, size_t, int);
30extern int v9fs_xattr_set(struct dentry *, const char *, 32extern int v9fs_xattr_set(struct dentry *, const char *,
31 const void *, size_t, int); 33 const void *, size_t, int);
32extern ssize_t v9fs_listxattr(struct dentry *, char *, size_t); 34extern ssize_t v9fs_listxattr(struct dentry *, char *, size_t);