GlusterFS 编码规范

GlusterFS 编码规范

1. 每个结构成员需要有一条能够说明其用途的注释

Bad:

         gf_lock_t lock; /* lock */

Good:

         DBTYPE access_mode; /* access mode for accessing

                                     *the databases, can be

                                     *DB_HASH, DB_BTREE

                                     *(option access-mode <mode>)

                                     */

 

2. 在函数的开始声明所有变量

所有函数中的局部变量必须在"{ "之后立刻声明,这样可以帮助跟踪在退出时需要free的内存,同时还有助于debug,因为gdb不能处理在循环或者类似的块中声明的变量

 

 

3. 永远要初始化变量

每个局部变量需要在声明的时候就被初始化到一个合理的初值,所有的指针需要初始化为NULL,所有的整数需要初始化为零,或者一个错误代码。

Good:

         int ret = 0;

         char *databuf = NULL;

         int _fd = -1;

 

4. 永远用常量来初始化

不要用一个表达式来初始化变量

Bad:

pid_t pid = frame->root->pid;

char *databuf = malloc (1024);

 

5. 验证函数的所有参数

需要检查所有指针类型的参数是否为NULL.

在common-utils.h中定义的宏 VALIDATE,可以验证一个参数是否为NULL,如果是,则写一条log然后跳到err标志处

 

Good:

VALIDATE(frame);

VALIDATE(this);

VALIDATE(inode);

 

6. 不要依赖于操作符优先级(健忘症者的福音)

这样的代码很难读,也许其它人没有你对优先级了解的那么多

 

Bad:

if (op_ret == -1 && errno != ENOENT)

Good:

if ((op_ret == -1) && (errno != ENOENT))

 

7. 使用精确的数据类型

使用库函数在manual中声明的返回类型,不要用他们的"等价类型"

Bad:

int len = strlen (path);

Good:

size_t len = strlen (path);

 

8. 不要写类似foo->bar->baz的 指针链

在使用之前需要检查所有指针是否为NULL

 

9. 检查所有的系统调用或者API函数的返回值(success|failure.

Bad:

close (fd);

Good:

op_ret = close (_fd);

if (op_ret == -1) {

gf_log (this->name, GF_LOG_ERROR,

"close on file %s failed (%s)", real_path,

strerror (errno));

op_errno = errno;

goto out;

}

 

10.优雅的处理malloc错误

GlusterFS不应该因为缺少内存crash或者退出,如果内存分配失败,调用应该被unwound,错误应该返回给用户

 

11. 使用返回参数,并且保留函数返回值,来说明函数的成功和失败

如果一个函数需要返回更多的数据,使用指针,返回值一般用来标识函数是否成功。

Bad:

int32_t dict_get_int32 (dict_t *this, char *key);

 

Good:

int dict_get_int32 (dict_t *this, char *key, int32_t *val);

 

12. 使用带“n”的字符串函数

 

Bad:

strcpy (entry_path, real_path);

Good:

strncpy (entry_path, real_path, entry_path_len);

 

13. 不应该有从来不被执行的代码,或者被注释掉得代码

 

14. 每个函数中只有一个地方可以UNWIND或者返回

 

15. 控制每个函数的规模

每个函数控制在2到3页(80行),超过这个规模可以写多个helper函数

 

helper函数的例子

static int

same_owner (posix_lock_t *l1, posix_lock_t *l2)

{

return ((l1->client_pid == l2->client_pid) &&

(l1->transport == l2->transport));

}

 

代码风格

括号的位置

使用K&R/Linux 风格

int some_function (...)
{

if (...) {

/* ... */

} else if (...) {

/* ... */

} else {

/* ... */

}

do {

/* ... */

} while (cond);

}

缩进

使用8个空格,并且保证代码中只有空格没有tab

 

注释

在每个函数之前写一个注释描述他的功能,参数和返回值,说明它是 一个内部函数还是函数

在每个结构之前写一个注释,对每个结构成员写注释

例子:

/**

* hash_name -hash function for filenames

* @par: parent inode number

* @name: basename of inode

* @mod: number of buckets in the hashtable

*

* @return: success: bucket number

* failure: -1

*

* Not for external use.

*/

 

 

突出显示竞争区域

 

 pthread_mutex_lock (&mutex);
{

/* code */

}
pthread_mutex_unlock (&mutex);

 

一个fop的代码框架

 

首先是初始化,然后是参数检查,所有的错误都会goto 到唯一点"out",在这个地方,代码将检查错误的类型,然后做相应的清理。

 

int32_t

sample_fop (call_frame_t *frame,

xlator_t *this,

...)

{

         char * var1 = NULL;

         int32_t op_ret = -1;

         int32_t op_errno = 0;

         DIR * dir = NULL;

         struct posix_fd * pfd =NULL;

         VALIDATE_OR_GOTO (frame,out);

         VALIDATE_OR_GOTO (this,out);

         /* other validations */

         dir = opendir (...);

         if (dir == NULL) {

                   op_errno = errno;

                   gf_log (this->name,GF_LOG_ERROR,

                   "opendirfailed on %s (%s)", loc->path,

                   strerror(op_errno));

                   goto out;

         }

         /* another system call */

         if (...) {

                   op_errno = ENOMEM;

                   gf_log(this->name, GF_LOG_ERROR,

                   "out ofmemory :(");

                   goto out;

         }

         /* ... */

out:

         if (op_ret == -1) {

         /* check for all the cleanupthat needs to be

                   done */

                   if (dir) {

         closedir (dir);

         dir = NULL;

         }

         if (pfd) {

                   if (pfd->path)

                   FREE(pfd->path);

                   FREE (pfd);

                   pfd = NULL;

         }

         }

         STACK_UNWIND (frame, op_ret,op_errno, fd);

         return 0;

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值