@@ -2449,6 +2449,7 @@ int ceph_getattr(struct user_namespace *mnt_userns, const struct path *path,
24492449 struct kstat * stat , u32 request_mask , unsigned int flags )
24502450{
24512451 struct inode * inode = d_inode (path -> dentry );
2452+ struct super_block * sb = inode -> i_sb ;
24522453 struct ceph_inode_info * ci = ceph_inode (inode );
24532454 u32 valid_mask = STATX_BASIC_STATS ;
24542455 int err = 0 ;
@@ -2478,16 +2479,34 @@ int ceph_getattr(struct user_namespace *mnt_userns, const struct path *path,
24782479 }
24792480
24802481 if (ceph_snap (inode ) == CEPH_NOSNAP )
2481- stat -> dev = inode -> i_sb -> s_dev ;
2482+ stat -> dev = sb -> s_dev ;
24822483 else
24832484 stat -> dev = ci -> i_snapid_map ? ci -> i_snapid_map -> dev : 0 ;
24842485
24852486 if (S_ISDIR (inode -> i_mode )) {
2486- if (ceph_test_mount_opt (ceph_sb_to_client (inode -> i_sb ),
2487- RBYTES ))
2487+ if (ceph_test_mount_opt (ceph_sb_to_client (sb ), RBYTES )) {
24882488 stat -> size = ci -> i_rbytes ;
2489- else
2489+ } else if (ceph_snap (inode ) == CEPH_SNAPDIR ) {
2490+ struct ceph_inode_info * pci ;
2491+ struct ceph_snap_realm * realm ;
2492+ struct inode * parent ;
2493+
2494+ parent = ceph_lookup_inode (sb , ceph_ino (inode ));
2495+ if (!parent )
2496+ return PTR_ERR (parent );
2497+
2498+ pci = ceph_inode (parent );
2499+ spin_lock (& pci -> i_ceph_lock );
2500+ realm = pci -> i_snap_realm ;
2501+ if (realm )
2502+ stat -> size = realm -> num_snaps ;
2503+ else
2504+ stat -> size = 0 ;
2505+ spin_unlock (& pci -> i_ceph_lock );
2506+ iput (parent );
2507+ } else {
24902508 stat -> size = ci -> i_files + ci -> i_subdirs ;
2509+ }
24912510 stat -> blocks = 0 ;
24922511 stat -> blksize = 65536 ;
24932512 /*
0 commit comments