@@ -366,6 +366,12 @@ int ceph_open(struct inode *inode, struct file *file)
366
366
struct ceph_file_info * fi = file -> private_data ;
367
367
int err ;
368
368
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 ;
369
375
370
376
if (fi ) {
371
377
doutc (cl , "file %p is already opened\n" , file );
@@ -387,6 +393,31 @@ int ceph_open(struct inode *inode, struct file *file)
387
393
fmode = ceph_flags_to_mode (flags );
388
394
wanted = ceph_caps_for_mode (fmode );
389
395
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
+
390
421
/* snapped files are read-only */
391
422
if (ceph_snap (inode ) != CEPH_NOSNAP && (file -> f_mode & FMODE_WRITE ))
392
423
return - EROFS ;
@@ -402,7 +433,7 @@ int ceph_open(struct inode *inode, struct file *file)
402
433
* asynchronously.
403
434
*/
404
435
spin_lock (& ci -> i_ceph_lock );
405
- if (__ceph_is_any_real_caps (ci ) &&
436
+ if (! do_sync && __ceph_is_any_real_caps (ci ) &&
406
437
(((fmode & CEPH_FILE_MODE_WR ) == 0 ) || ci -> i_auth_cap )) {
407
438
int mds_wanted = __ceph_caps_mds_wanted (ci , true);
408
439
int issued = __ceph_caps_issued (ci , NULL );
@@ -420,7 +451,7 @@ int ceph_open(struct inode *inode, struct file *file)
420
451
ceph_check_caps (ci , 0 );
421
452
422
453
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 &&
424
455
(ci -> i_snap_caps & wanted ) == wanted ) {
425
456
__ceph_touch_fmode (ci , mdsc , fmode );
426
457
spin_unlock (& ci -> i_ceph_lock );
0 commit comments