@@ -366,6 +366,12 @@ int ceph_open(struct inode *inode, struct file *file)
366366 struct ceph_file_info * fi = file -> private_data ;
367367 int err ;
368368 int flags , fmode , wanted ;
369+ struct dentry * dentry ;
370+ char * path ;
371+ int pathlen ;
372+ u64 pathbase ;
373+ bool do_sync = false;
374+ int mask = MAY_READ ;
369375
370376 if (fi ) {
371377 doutc (cl , "file %p is already opened\n" , file );
@@ -387,6 +393,31 @@ int ceph_open(struct inode *inode, struct file *file)
387393 fmode = ceph_flags_to_mode (flags );
388394 wanted = ceph_caps_for_mode (fmode );
389395
396+ if (fmode & CEPH_FILE_MODE_WR )
397+ mask |= MAY_WRITE ;
398+ dentry = d_find_alias (inode );
399+ if (!dentry ) {
400+ do_sync = true;
401+ } else {
402+ path = ceph_mdsc_build_path (mdsc , dentry , & pathlen , & pathbase , 0 );
403+ if (IS_ERR (path )) {
404+ do_sync = true;
405+ err = 0 ;
406+ } else {
407+ err = ceph_mds_check_access (mdsc , path , mask );
408+ }
409+ ceph_mdsc_free_path (path , pathlen );
410+ dput (dentry );
411+
412+ /* For none EACCES cases will let the MDS do the mds auth check */
413+ if (err == - EACCES ) {
414+ return err ;
415+ } else if (err < 0 ) {
416+ do_sync = true;
417+ err = 0 ;
418+ }
419+ }
420+
390421 /* snapped files are read-only */
391422 if (ceph_snap (inode ) != CEPH_NOSNAP && (file -> f_mode & FMODE_WRITE ))
392423 return - EROFS ;
@@ -402,7 +433,7 @@ int ceph_open(struct inode *inode, struct file *file)
402433 * asynchronously.
403434 */
404435 spin_lock (& ci -> i_ceph_lock );
405- if (__ceph_is_any_real_caps (ci ) &&
436+ if (! do_sync && __ceph_is_any_real_caps (ci ) &&
406437 (((fmode & CEPH_FILE_MODE_WR ) == 0 ) || ci -> i_auth_cap )) {
407438 int mds_wanted = __ceph_caps_mds_wanted (ci , true);
408439 int issued = __ceph_caps_issued (ci , NULL );
@@ -420,7 +451,7 @@ int ceph_open(struct inode *inode, struct file *file)
420451 ceph_check_caps (ci , 0 );
421452
422453 return ceph_init_file (inode , file , fmode );
423- } else if (ceph_snap (inode ) != CEPH_NOSNAP &&
454+ } else if (! do_sync && ceph_snap (inode ) != CEPH_NOSNAP &&
424455 (ci -> i_snap_caps & wanted ) == wanted ) {
425456 __ceph_touch_fmode (ci , mdsc , fmode );
426457 spin_unlock (& ci -> i_ceph_lock );
0 commit comments