@@ -48,6 +48,8 @@ static DECLARE_DELAYED_WORK(afs_mntpt_expiry_timer, afs_mntpt_expiry_timed_out);
48
48
49
49
static unsigned long afs_mntpt_expiry_timeout = 10 * 60 ;
50
50
51
+ static const char afs_root_volume [] = "root.cell" ;
52
+
51
53
/*
52
54
* no valid lookup procedure on this sort of dir
53
55
*/
@@ -69,108 +71,112 @@ static int afs_mntpt_open(struct inode *inode, struct file *file)
69
71
}
70
72
71
73
/*
72
- * create a vfsmount to be automounted
74
+ * Set the parameters for the proposed superblock.
73
75
*/
74
- static struct vfsmount * afs_mntpt_do_automount ( struct dentry * mntpt )
76
+ static int afs_mntpt_set_params ( struct fs_context * fc , struct dentry * mntpt )
75
77
{
76
- struct afs_super_info * as ;
77
- struct vfsmount * mnt ;
78
- struct afs_vnode * vnode ;
79
- struct page * page ;
80
- char * devname , * options ;
81
- bool rwpath = false;
78
+ struct afs_fs_context * ctx = fc -> fs_private ;
79
+ struct afs_super_info * src_as = AFS_FS_S (mntpt -> d_sb );
80
+ struct afs_vnode * vnode = AFS_FS_I (d_inode (mntpt ));
81
+ struct afs_cell * cell ;
82
+ const char * p ;
82
83
int ret ;
83
84
84
- _enter ("{%pd}" , mntpt );
85
-
86
- BUG_ON (!d_inode (mntpt ));
87
-
88
- ret = - ENOMEM ;
89
- devname = (char * ) get_zeroed_page (GFP_KERNEL );
90
- if (!devname )
91
- goto error_no_devname ;
92
-
93
- options = (char * ) get_zeroed_page (GFP_KERNEL );
94
- if (!options )
95
- goto error_no_options ;
85
+ if (fc -> net_ns != src_as -> net_ns ) {
86
+ put_net (fc -> net_ns );
87
+ fc -> net_ns = get_net (src_as -> net_ns );
88
+ }
96
89
97
- vnode = AFS_FS_I (d_inode (mntpt ));
90
+ if (src_as -> volume && src_as -> volume -> type == AFSVL_RWVOL ) {
91
+ ctx -> type = AFSVL_RWVOL ;
92
+ ctx -> force = true;
93
+ }
94
+ if (ctx -> cell ) {
95
+ afs_put_cell (ctx -> net , ctx -> cell );
96
+ ctx -> cell = NULL ;
97
+ }
98
98
if (test_bit (AFS_VNODE_PSEUDODIR , & vnode -> flags )) {
99
99
/* if the directory is a pseudo directory, use the d_name */
100
- static const char afs_root_cell [] = ":root.cell." ;
101
100
unsigned size = mntpt -> d_name .len ;
102
101
103
- ret = - ENOENT ;
104
- if (size < 2 || size > AFS_MAXCELLNAME )
105
- goto error_no_page ;
102
+ if (size < 2 )
103
+ return - ENOENT ;
106
104
105
+ p = mntpt -> d_name .name ;
107
106
if (mntpt -> d_name .name [0 ] == '.' ) {
108
- devname [0 ] = '%' ;
109
- memcpy (devname + 1 , mntpt -> d_name .name + 1 , size - 1 );
110
- memcpy (devname + size , afs_root_cell ,
111
- sizeof (afs_root_cell ));
112
- rwpath = true;
113
- } else {
114
- devname [0 ] = '#' ;
115
- memcpy (devname + 1 , mntpt -> d_name .name , size );
116
- memcpy (devname + size + 1 , afs_root_cell ,
117
- sizeof (afs_root_cell ));
107
+ size -- ;
108
+ p ++ ;
109
+ ctx -> type = AFSVL_RWVOL ;
110
+ ctx -> force = true;
118
111
}
112
+ if (size > AFS_MAXCELLNAME )
113
+ return - ENAMETOOLONG ;
114
+
115
+ cell = afs_lookup_cell (ctx -> net , p , size , NULL , false);
116
+ if (IS_ERR (cell )) {
117
+ pr_err ("kAFS: unable to lookup cell '%pd'\n" , mntpt );
118
+ return PTR_ERR (cell );
119
+ }
120
+ ctx -> cell = cell ;
121
+
122
+ ctx -> volname = afs_root_volume ;
123
+ ctx -> volnamesz = sizeof (afs_root_volume ) - 1 ;
119
124
} else {
120
125
/* read the contents of the AFS special symlink */
126
+ struct page * page ;
121
127
loff_t size = i_size_read (d_inode (mntpt ));
122
128
char * buf ;
123
129
124
- ret = - EINVAL ;
130
+ if (src_as -> cell )
131
+ ctx -> cell = afs_get_cell (src_as -> cell );
132
+
125
133
if (size > PAGE_SIZE - 1 )
126
- goto error_no_page ;
134
+ return - EINVAL ;
127
135
128
136
page = read_mapping_page (d_inode (mntpt )-> i_mapping , 0 , NULL );
129
- if (IS_ERR (page )) {
130
- ret = PTR_ERR (page );
131
- goto error_no_page ;
132
- }
137
+ if (IS_ERR (page ))
138
+ return PTR_ERR (page );
133
139
134
140
if (PageError (page )) {
135
141
ret = afs_bad (AFS_FS_I (d_inode (mntpt )), afs_file_error_mntpt );
136
- goto error ;
142
+ put_page (page );
143
+ return ret ;
137
144
}
138
145
139
- buf = kmap_atomic (page );
140
- memcpy ( devname , buf , size );
141
- kunmap_atomic ( buf );
146
+ buf = kmap (page );
147
+ ret = vfs_parse_fs_string ( fc , "source" , buf , size );
148
+ kunmap ( page );
142
149
put_page (page );
143
- page = NULL ;
150
+ if (ret < 0 )
151
+ return ret ;
144
152
}
145
153
146
- /* work out what options we want */
147
- as = AFS_FS_S (mntpt -> d_sb );
148
- if (as -> cell ) {
149
- memcpy (options , "cell=" , 5 );
150
- strcpy (options + 5 , as -> cell -> name );
151
- if ((as -> volume && as -> volume -> type == AFSVL_RWVOL ) || rwpath )
152
- strcat (options , ",rwpath" );
153
- }
154
+ return 0 ;
155
+ }
154
156
155
- /* try and do the mount */
156
- _debug ("--- attempting mount %s -o %s ---" , devname , options );
157
- mnt = vfs_submount (mntpt , & afs_fs_type , devname , options );
158
- _debug ("--- mount result %p ---" , mnt );
157
+ /*
158
+ * create a vfsmount to be automounted
159
+ */
160
+ static struct vfsmount * afs_mntpt_do_automount (struct dentry * mntpt )
161
+ {
162
+ struct fs_context * fc ;
163
+ struct vfsmount * mnt ;
164
+ int ret ;
159
165
160
- free_page ((unsigned long ) devname );
161
- free_page ((unsigned long ) options );
162
- _leave (" = %p" , mnt );
163
- return mnt ;
166
+ BUG_ON (!d_inode (mntpt ));
164
167
165
- error :
166
- put_page (page );
167
- error_no_page :
168
- free_page ((unsigned long ) options );
169
- error_no_options :
170
- free_page ((unsigned long ) devname );
171
- error_no_devname :
172
- _leave (" = %d" , ret );
173
- return ERR_PTR (ret );
168
+ fc = fs_context_for_submount (& afs_fs_type , mntpt );
169
+ if (IS_ERR (fc ))
170
+ return ERR_CAST (fc );
171
+
172
+ ret = afs_mntpt_set_params (fc , mntpt );
173
+ if (!ret )
174
+ mnt = fc_mount (fc );
175
+ else
176
+ mnt = ERR_PTR (ret );
177
+
178
+ put_fs_context (fc );
179
+ return mnt ;
174
180
}
175
181
176
182
/*
0 commit comments